aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-03 16:56:08 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-03 16:56:08 +0000
commit8a24f25482f07eecab254c93223369fa532c076f (patch)
treeae9f92ffafd9cde25e6e9e82f246bbe566a23655 /crates/ra_analysis/src
parent36af3100f9e16188dff4e9a348901a4f18c93b81 (diff)
parent9bb2a742564fc893f5b8e1e605c760798e102765 (diff)
Merge #419
419: file-id-to-symbol r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r--crates/ra_analysis/src/imp.rs22
-rw-r--r--crates/ra_analysis/src/lib.rs11
-rw-r--r--crates/ra_analysis/src/symbol_index.rs36
3 files changed, 34 insertions, 35 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 771dad475..eae73c2c4 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -165,9 +165,11 @@ impl db::RootDatabase {
165 }; 165 };
166 } 166 }
167 // If that fails try the index based approach. 167 // If that fails try the index based approach.
168 for (file_id, symbol) in self.index_resolve(name_ref)? { 168 rr.resolves_to.extend(
169 rr.add_resolution(file_id, symbol); 169 self.index_resolve(name_ref)?
170 } 170 .into_iter()
171 .map(NavigationTarget::from_symbol),
172 );
171 return Ok(Some(rr)); 173 return Ok(Some(rr));
172 } 174 }
173 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { 175 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) {
@@ -352,13 +354,15 @@ impl db::RootDatabase {
352 354
353 // Resolve the function's NameRef (NOTE: this isn't entirely accurate). 355 // Resolve the function's NameRef (NOTE: this isn't entirely accurate).
354 let file_symbols = self.index_resolve(name_ref)?; 356 let file_symbols = self.index_resolve(name_ref)?;
355 for (fn_file_id, fs) in file_symbols { 357 for symbol in file_symbols {
356 if fs.ptr.kind() == FN_DEF { 358 if symbol.ptr.kind() == FN_DEF {
357 let fn_file = self.source_file(fn_file_id); 359 let fn_file = self.source_file(symbol.file_id);
358 let fn_def = fs.ptr.resolve(&fn_file); 360 let fn_def = symbol.ptr.resolve(&fn_file);
359 let fn_def = ast::FnDef::cast(fn_def.borrowed()).unwrap(); 361 let fn_def = ast::FnDef::cast(fn_def.borrowed()).unwrap();
360 let descr = ctry!(source_binder::function_from_source( 362 let descr = ctry!(source_binder::function_from_source(
361 self, fn_file_id, fn_def 363 self,
364 symbol.file_id,
365 fn_def
362 )?); 366 )?);
363 if let Some(descriptor) = descr.signature_info(self) { 367 if let Some(descriptor) = descr.signature_info(self) {
364 // If we have a calling expression let's find which argument we are on 368 // If we have a calling expression let's find which argument we are on
@@ -438,7 +442,7 @@ impl db::RootDatabase {
438 .collect::<Vec<_>>(); 442 .collect::<Vec<_>>();
439 Ok(res) 443 Ok(res)
440 } 444 }
441 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> { 445 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<FileSymbol>> {
442 let name = name_ref.text(); 446 let name = name_ref.text();
443 let mut query = Query::new(name.to_string()); 447 let mut query = Query::new(name.to_string());
444 query.exact(); 448 query.exact();
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 61af676b2..ab935954c 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -237,11 +237,11 @@ pub struct NavigationTarget {
237} 237}
238 238
239impl NavigationTarget { 239impl NavigationTarget {
240 fn from_symbol(file_id: FileId, symbol: FileSymbol) -> NavigationTarget { 240 fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
241 NavigationTarget { 241 NavigationTarget {
242 file_id: symbol.file_id,
242 name: symbol.name.clone(), 243 name: symbol.name.clone(),
243 kind: symbol.ptr.kind(), 244 kind: symbol.ptr.kind(),
244 file_id,
245 range: symbol.ptr.range(), 245 range: symbol.ptr.range(),
246 ptr: Some(symbol.ptr.clone()), 246 ptr: Some(symbol.ptr.clone()),
247 } 247 }
@@ -278,11 +278,6 @@ impl ReferenceResolution {
278 resolves_to: Vec::new(), 278 resolves_to: Vec::new(),
279 } 279 }
280 } 280 }
281
282 fn add_resolution(&mut self, file_id: FileId, symbol: FileSymbol) {
283 self.resolves_to
284 .push(NavigationTarget::from_symbol(file_id, symbol))
285 }
286} 281}
287 282
288/// `AnalysisHost` stores the current state of the world. 283/// `AnalysisHost` stores the current state of the world.
@@ -380,7 +375,7 @@ impl Analysis {
380 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { 375 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> {
381 let res = symbol_index::world_symbols(&*self.db, query)? 376 let res = symbol_index::world_symbols(&*self.db, query)?
382 .into_iter() 377 .into_iter()
383 .map(|(file_id, symbol)| NavigationTarget::from_symbol(file_id, symbol)) 378 .map(NavigationTarget::from_symbol)
384 .collect(); 379 .collect();
385 Ok(res) 380 Ok(res)
386 } 381 }
diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs
index 10d8e8059..b355b14ed 100644
--- a/crates/ra_analysis/src/symbol_index.rs
+++ b/crates/ra_analysis/src/symbol_index.rs
@@ -58,10 +58,7 @@ fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable<Arc<Sym
58 Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) 58 Ok(Arc::new(SymbolIndex::for_file(file_id, syntax)))
59} 59}
60 60
61pub(crate) fn world_symbols( 61pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Cancelable<Vec<FileSymbol>> {
62 db: &RootDatabase,
63 query: Query,
64) -> Cancelable<Vec<(FileId, FileSymbol)>> {
65 /// Need to wrap Snapshot to provide `Clone` impl for `map_with` 62 /// Need to wrap Snapshot to provide `Clone` impl for `map_with`
66 struct Snap(salsa::Snapshot<RootDatabase>); 63 struct Snap(salsa::Snapshot<RootDatabase>);
67 impl Clone for Snap { 64 impl Clone for Snap {
@@ -95,7 +92,7 @@ pub(crate) fn world_symbols(
95 92
96#[derive(Default, Debug)] 93#[derive(Default, Debug)]
97pub(crate) struct SymbolIndex { 94pub(crate) struct SymbolIndex {
98 symbols: Vec<(FileId, FileSymbol)>, 95 symbols: Vec<FileSymbol>,
99 map: fst::Map, 96 map: fst::Map,
100} 97}
101 98
@@ -126,14 +123,18 @@ impl SymbolIndex {
126 file.syntax() 123 file.syntax()
127 .descendants() 124 .descendants()
128 .filter_map(to_symbol) 125 .filter_map(to_symbol)
129 .map(move |symbol| (symbol.name.as_str().to_lowercase(), (file_id, symbol))) 126 .map(move |(name, ptr)| {
127 (
128 name.as_str().to_lowercase(),
129 FileSymbol { name, ptr, file_id },
130 )
131 })
130 .collect::<Vec<_>>() 132 .collect::<Vec<_>>()
131 }) 133 })
132 .collect::<Vec<_>>(); 134 .collect::<Vec<_>>();
133 symbols.par_sort_by(|s1, s2| s1.0.cmp(&s2.0)); 135 symbols.par_sort_by(|s1, s2| s1.0.cmp(&s2.0));
134 symbols.dedup_by(|s1, s2| s1.0 == s2.0); 136 symbols.dedup_by(|s1, s2| s1.0 == s2.0);
135 let (names, symbols): (Vec<String>, Vec<(FileId, FileSymbol)>) = 137 let (names, symbols): (Vec<String>, Vec<FileSymbol>) = symbols.into_iter().unzip();
136 symbols.into_iter().unzip();
137 let map = fst::Map::from_iter(names.into_iter().zip(0u64..)).unwrap(); 138 let map = fst::Map::from_iter(names.into_iter().zip(0u64..)).unwrap();
138 SymbolIndex { symbols, map } 139 SymbolIndex { symbols, map }
139 } 140 }
@@ -144,7 +145,7 @@ impl SymbolIndex {
144} 145}
145 146
146impl Query { 147impl Query {
147 pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<(FileId, FileSymbol)> { 148 pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<FileSymbol> {
148 let mut op = fst::map::OpBuilder::new(); 149 let mut op = fst::map::OpBuilder::new();
149 for file_symbols in indices.iter() { 150 for file_symbols in indices.iter() {
150 let automaton = fst::automaton::Subsequence::new(&self.lowercased); 151 let automaton = fst::automaton::Subsequence::new(&self.lowercased);
@@ -160,14 +161,14 @@ impl Query {
160 let file_symbols = &indices[indexed_value.index]; 161 let file_symbols = &indices[indexed_value.index];
161 let idx = indexed_value.value as usize; 162 let idx = indexed_value.value as usize;
162 163
163 let (file_id, symbol) = &file_symbols.symbols[idx]; 164 let symbol = &file_symbols.symbols[idx];
164 if self.only_types && !is_type(symbol.ptr.kind()) { 165 if self.only_types && !is_type(symbol.ptr.kind()) {
165 continue; 166 continue;
166 } 167 }
167 if self.exact && symbol.name != self.query { 168 if self.exact && symbol.name != self.query {
168 continue; 169 continue;
169 } 170 }
170 res.push((*file_id, symbol.clone())); 171 res.push(symbol.clone());
171 } 172 }
172 } 173 }
173 res 174 res
@@ -185,17 +186,16 @@ fn is_type(kind: SyntaxKind) -> bool {
185/// possible. 186/// possible.
186#[derive(Debug, Clone, PartialEq, Eq, Hash)] 187#[derive(Debug, Clone, PartialEq, Eq, Hash)]
187pub(crate) struct FileSymbol { 188pub(crate) struct FileSymbol {
189 pub(crate) file_id: FileId,
188 pub(crate) name: SmolStr, 190 pub(crate) name: SmolStr,
189 pub(crate) ptr: LocalSyntaxPtr, 191 pub(crate) ptr: LocalSyntaxPtr,
190} 192}
191 193
192fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { 194fn to_symbol(node: SyntaxNodeRef) -> Option<(SmolStr, LocalSyntaxPtr)> {
193 fn decl<'a, N: NameOwner<'a>>(node: N) -> Option<FileSymbol> { 195 fn decl<'a, N: NameOwner<'a>>(node: N) -> Option<(SmolStr, LocalSyntaxPtr)> {
194 let name = node.name()?; 196 let name = node.name()?.text();
195 Some(FileSymbol { 197 let ptr = LocalSyntaxPtr::new(node.syntax());
196 name: name.text(), 198 Some((name, ptr))
197 ptr: LocalSyntaxPtr::new(node.syntax()),
198 })
199 } 199 }
200 visitor() 200 visitor()
201 .visit(decl::<ast::FnDef>) 201 .visit(decl::<ast::FnDef>)