diff options
author | Aleksey Kladov <[email protected]> | 2018-11-27 11:11:36 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-11-27 12:02:06 +0000 |
commit | 10f4d4b74cd7e072bf5e8d3fb57c76f35ea03e1d (patch) | |
tree | ec9c94fa1bf857032b3914175d03fd179f74c660 | |
parent | 4d87799a4a73e5a58fce4e3caa88ad90347bdabb (diff) |
Make nameresolution resilient to reparsing
We now store item id's instead of local syntax ptrs, and item ids
don't change if you type inside a single function.
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 7 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 5 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/nameres.rs | 182 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/path.rs | 19 | ||||
-rw-r--r-- | crates/ra_analysis/src/loc2id.rs | 5 | ||||
-rw-r--r-- | crates/ra_analysis/src/syntax_ptr.rs | 5 |
6 files changed, 139 insertions, 84 deletions
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index d301a3c02..1faa70a18 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs | |||
@@ -46,9 +46,12 @@ pub(super) fn completions( | |||
46 | .iter() | 46 | .iter() |
47 | .filter(|(_name, res)| { | 47 | .filter(|(_name, res)| { |
48 | // Don't expose this item | 48 | // Don't expose this item |
49 | match res.import_name { | 49 | match res.import { |
50 | None => true, | 50 | None => true, |
51 | Some(ptr) => !ptr.range().is_subrange(&name_ref.syntax().range()), | 51 | Some(import) => { |
52 | let range = import.range(db, module.source().file_id()); | ||
53 | !range.is_subrange(&name_ref.syntax().range()) | ||
54 | } | ||
52 | } | 55 | } |
53 | }) | 56 | }) |
54 | .map(|(name, _res)| CompletionItem { | 57 | .map(|(name, _res)| CompletionItem { |
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index f6b9102e7..a5e956024 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs | |||
@@ -13,7 +13,7 @@ use crate::{ | |||
13 | FileId, | 13 | FileId, |
14 | db::SyntaxDatabase, | 14 | db::SyntaxDatabase, |
15 | descriptors::function::{resolve_local_name, FnId, FnScopes}, | 15 | descriptors::function::{resolve_local_name, FnId, FnScopes}, |
16 | descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItemId}}, | 16 | descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItems}}, |
17 | input::SourceRootId, | 17 | input::SourceRootId, |
18 | loc2id::IdDatabase, | 18 | loc2id::IdDatabase, |
19 | syntax_ptr::LocalSyntaxPtr, | 19 | syntax_ptr::LocalSyntaxPtr, |
@@ -21,6 +21,7 @@ use crate::{ | |||
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub(crate) use self::path::{Path, PathKind}; | 23 | pub(crate) use self::path::{Path, PathKind}; |
24 | pub(crate) use self::module::nameres::FileItemId; | ||
24 | 25 | ||
25 | salsa::query_group! { | 26 | salsa::query_group! { |
26 | pub(crate) trait DescriptorDatabase: SyntaxDatabase + IdDatabase { | 27 | pub(crate) trait DescriptorDatabase: SyntaxDatabase + IdDatabase { |
@@ -29,7 +30,7 @@ salsa::query_group! { | |||
29 | use fn function::imp::fn_scopes; | 30 | use fn function::imp::fn_scopes; |
30 | } | 31 | } |
31 | 32 | ||
32 | fn _file_items(file_id: FileId) -> Arc<Vec<SyntaxNode>> { | 33 | fn _file_items(file_id: FileId) -> Arc<FileItems> { |
33 | type FileItemsQuery; | 34 | type FileItemsQuery; |
34 | storage volatile; | 35 | storage volatile; |
35 | use fn module::nameres::file_items; | 36 | use fn module::nameres::file_items; |
diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index 6e327e374..d347a69b0 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs | |||
@@ -17,12 +17,13 @@ | |||
17 | use std::{ | 17 | use std::{ |
18 | sync::Arc, | 18 | sync::Arc, |
19 | time::Instant, | 19 | time::Instant, |
20 | ops::Index, | ||
20 | }; | 21 | }; |
21 | 22 | ||
22 | use rustc_hash::FxHashMap; | 23 | use rustc_hash::FxHashMap; |
23 | 24 | ||
24 | use ra_syntax::{ | 25 | use ra_syntax::{ |
25 | SyntaxNode, | 26 | SyntaxNode, SyntaxNodeRef, TextRange, |
26 | SmolStr, SyntaxKind::{self, *}, | 27 | SmolStr, SyntaxKind::{self, *}, |
27 | ast::{self, ModuleItemOwner, AstNode} | 28 | ast::{self, ModuleItemOwner, AstNode} |
28 | }; | 29 | }; |
@@ -35,28 +36,62 @@ use crate::{ | |||
35 | DescriptorDatabase, | 36 | DescriptorDatabase, |
36 | module::{ModuleId, ModuleTree, ModuleSourceNode}, | 37 | module::{ModuleId, ModuleTree, ModuleSourceNode}, |
37 | }, | 38 | }, |
38 | syntax_ptr::{LocalSyntaxPtr}, | ||
39 | input::SourceRootId, | 39 | input::SourceRootId, |
40 | arena::{Arena, Id} | ||
40 | }; | 41 | }; |
41 | 42 | ||
43 | /// Identifier of item within a specific file. This is stable over reparses, so | ||
44 | /// it's OK to use it as a salsa key/value. | ||
45 | pub(crate) type FileItemId = Id<SyntaxNode>; | ||
42 | 46 | ||
43 | #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] | 47 | /// Maps item's `SyntaxNode`s to `FileItemId` and back. |
44 | pub(crate) struct FileItemId(u32); | 48 | #[derive(Debug, PartialEq, Eq, Default)] |
49 | pub(crate) struct FileItems { | ||
50 | arena: Arena<SyntaxNode>, | ||
51 | } | ||
52 | |||
53 | impl FileItems { | ||
54 | fn alloc(&mut self, item: SyntaxNode) -> FileItemId { | ||
55 | self.arena.alloc(item) | ||
56 | } | ||
57 | fn id_of(&self, item: SyntaxNodeRef) -> FileItemId { | ||
58 | let (id, _item) = self | ||
59 | .arena | ||
60 | .iter() | ||
61 | .find(|(_id, i)| i.borrowed() == item) | ||
62 | .unwrap(); | ||
63 | id | ||
64 | } | ||
65 | } | ||
45 | 66 | ||
46 | pub(crate) fn file_items(db: &impl DescriptorDatabase, file_id: FileId) -> Arc<Vec<SyntaxNode>> { | 67 | impl Index<FileItemId> for FileItems { |
68 | type Output = SyntaxNode; | ||
69 | fn index(&self, idx: FileItemId) -> &SyntaxNode { | ||
70 | &self.arena[idx] | ||
71 | } | ||
72 | } | ||
73 | |||
74 | pub(crate) fn file_items(db: &impl DescriptorDatabase, file_id: FileId) -> Arc<FileItems> { | ||
47 | let source_file = db.file_syntax(file_id); | 75 | let source_file = db.file_syntax(file_id); |
48 | let source_file = source_file.borrowed(); | 76 | let source_file = source_file.borrowed(); |
49 | let res = source_file.syntax().descendants() | 77 | let mut res = FileItems::default(); |
78 | source_file | ||
79 | .syntax() | ||
80 | .descendants() | ||
50 | .filter_map(ast::ModuleItem::cast) | 81 | .filter_map(ast::ModuleItem::cast) |
51 | .map(|it| it.syntax().owned()) | 82 | .map(|it| it.syntax().owned()) |
52 | .collect::<Vec<_>>(); | 83 | .for_each(|it| { |
84 | res.alloc(it); | ||
85 | }); | ||
53 | Arc::new(res) | 86 | Arc::new(res) |
54 | } | 87 | } |
55 | 88 | ||
56 | pub(crate) fn file_item(db: &impl DescriptorDatabase, file_id: FileId, file_item_id: FileItemId) -> SyntaxNode { | 89 | pub(crate) fn file_item( |
57 | let items = db._file_items(file_id); | 90 | db: &impl DescriptorDatabase, |
58 | let idx = file_item_id.0 as usize; | 91 | file_id: FileId, |
59 | items[idx].clone() | 92 | file_item_id: FileItemId, |
93 | ) -> SyntaxNode { | ||
94 | db._file_items(file_id)[file_item_id].clone() | ||
60 | } | 95 | } |
61 | 96 | ||
62 | /// Item map is the result of the name resolution. Item map contains, for each | 97 | /// Item map is the result of the name resolution. Item map contains, for each |
@@ -83,17 +118,44 @@ pub(crate) struct InputModuleItems { | |||
83 | imports: Vec<Import>, | 118 | imports: Vec<Import>, |
84 | } | 119 | } |
85 | 120 | ||
121 | #[derive(Debug, PartialEq, Eq)] | ||
122 | struct ModuleItem { | ||
123 | id: FileItemId, | ||
124 | name: SmolStr, | ||
125 | kind: SyntaxKind, | ||
126 | vis: Vis, | ||
127 | } | ||
128 | |||
129 | #[derive(Debug, PartialEq, Eq)] | ||
130 | enum Vis { | ||
131 | // Priv, | ||
132 | Other, | ||
133 | } | ||
134 | |||
86 | #[derive(Debug, Clone, PartialEq, Eq)] | 135 | #[derive(Debug, Clone, PartialEq, Eq)] |
87 | struct Import { | 136 | struct Import { |
88 | path: Path, | 137 | path: Path, |
89 | kind: ImportKind, | 138 | kind: ImportKind, |
90 | } | 139 | } |
91 | 140 | ||
141 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
142 | pub(crate) struct NamedImport { | ||
143 | file_item_id: FileItemId, | ||
144 | relative_range: TextRange, | ||
145 | } | ||
146 | |||
147 | impl NamedImport { | ||
148 | pub(crate) fn range(&self, db: &impl DescriptorDatabase, file_id: FileId) -> TextRange { | ||
149 | let syntax = db._file_item(file_id, self.file_item_id); | ||
150 | let offset = syntax.borrowed().range().start(); | ||
151 | self.relative_range + offset | ||
152 | } | ||
153 | } | ||
154 | |||
92 | #[derive(Debug, Clone, PartialEq, Eq)] | 155 | #[derive(Debug, Clone, PartialEq, Eq)] |
93 | enum ImportKind { | 156 | enum ImportKind { |
94 | Glob, | 157 | Glob, |
95 | // TODO: make offset independent | 158 | Named(NamedImport), |
96 | Named(LocalSyntaxPtr), | ||
97 | } | 159 | } |
98 | 160 | ||
99 | pub(crate) fn input_module_items( | 161 | pub(crate) fn input_module_items( |
@@ -103,10 +165,11 @@ pub(crate) fn input_module_items( | |||
103 | ) -> Cancelable<Arc<InputModuleItems>> { | 165 | ) -> Cancelable<Arc<InputModuleItems>> { |
104 | let module_tree = db._module_tree(source_root)?; | 166 | let module_tree = db._module_tree(source_root)?; |
105 | let source = module_id.source(&module_tree); | 167 | let source = module_id.source(&module_tree); |
168 | let file_items = db._file_items(source.file_id()); | ||
106 | let res = match source.resolve(db) { | 169 | let res = match source.resolve(db) { |
107 | ModuleSourceNode::SourceFile(it) => { | 170 | ModuleSourceNode::SourceFile(it) => { |
108 | let items = it.borrowed().items(); | 171 | let items = it.borrowed().items(); |
109 | InputModuleItems::new(items) | 172 | InputModuleItems::new(&file_items, items) |
110 | } | 173 | } |
111 | ModuleSourceNode::Module(it) => { | 174 | ModuleSourceNode::Module(it) => { |
112 | let items = it | 175 | let items = it |
@@ -114,7 +177,7 @@ pub(crate) fn input_module_items( | |||
114 | .item_list() | 177 | .item_list() |
115 | .into_iter() | 178 | .into_iter() |
116 | .flat_map(|it| it.items()); | 179 | .flat_map(|it| it.items()); |
117 | InputModuleItems::new(items) | 180 | InputModuleItems::new(&file_items, items) |
118 | } | 181 | } |
119 | }; | 182 | }; |
120 | Ok(Arc::new(res)) | 183 | Ok(Arc::new(res)) |
@@ -133,7 +196,6 @@ pub(crate) fn item_map( | |||
133 | Ok((id, items)) | 196 | Ok((id, items)) |
134 | }) | 197 | }) |
135 | .collect::<Cancelable<FxHashMap<_, _>>>()?; | 198 | .collect::<Cancelable<FxHashMap<_, _>>>()?; |
136 | |||
137 | let mut resolver = Resolver { | 199 | let mut resolver = Resolver { |
138 | db: db, | 200 | db: db, |
139 | input: &input, | 201 | input: &input, |
@@ -155,8 +217,7 @@ pub(crate) struct Resolution { | |||
155 | /// None for unresolved | 217 | /// None for unresolved |
156 | pub(crate) def_id: Option<DefId>, | 218 | pub(crate) def_id: Option<DefId>, |
157 | /// ident by whitch this is imported into local scope. | 219 | /// ident by whitch this is imported into local scope. |
158 | /// TODO: make this offset-independent. | 220 | pub(crate) import: Option<NamedImport>, |
159 | pub(crate) import_name: Option<LocalSyntaxPtr>, | ||
160 | } | 221 | } |
161 | 222 | ||
162 | // #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | 223 | // #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
@@ -171,55 +232,49 @@ pub(crate) struct Resolution { | |||
171 | // values: Option<T>, | 232 | // values: Option<T>, |
172 | // } | 233 | // } |
173 | 234 | ||
174 | #[derive(Debug, PartialEq, Eq)] | ||
175 | struct ModuleItem { | ||
176 | ptr: LocalSyntaxPtr, | ||
177 | name: SmolStr, | ||
178 | kind: SyntaxKind, | ||
179 | vis: Vis, | ||
180 | } | ||
181 | |||
182 | #[derive(Debug, PartialEq, Eq)] | ||
183 | enum Vis { | ||
184 | // Priv, | ||
185 | Other, | ||
186 | } | ||
187 | |||
188 | impl InputModuleItems { | 235 | impl InputModuleItems { |
189 | fn new<'a>(items: impl Iterator<Item = ast::ModuleItem<'a>>) -> InputModuleItems { | 236 | fn new<'a>( |
237 | file_items: &FileItems, | ||
238 | items: impl Iterator<Item = ast::ModuleItem<'a>>, | ||
239 | ) -> InputModuleItems { | ||
190 | let mut res = InputModuleItems::default(); | 240 | let mut res = InputModuleItems::default(); |
191 | for item in items { | 241 | for item in items { |
192 | res.add_item(item); | 242 | res.add_item(file_items, item); |
193 | } | 243 | } |
194 | res | 244 | res |
195 | } | 245 | } |
196 | 246 | ||
197 | fn add_item(&mut self, item: ast::ModuleItem) -> Option<()> { | 247 | fn add_item(&mut self, file_items: &FileItems, item: ast::ModuleItem) -> Option<()> { |
198 | match item { | 248 | match item { |
199 | ast::ModuleItem::StructDef(it) => self.items.push(ModuleItem::new(it)?), | 249 | ast::ModuleItem::StructDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
200 | ast::ModuleItem::EnumDef(it) => self.items.push(ModuleItem::new(it)?), | 250 | ast::ModuleItem::EnumDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
201 | ast::ModuleItem::FnDef(it) => self.items.push(ModuleItem::new(it)?), | 251 | ast::ModuleItem::FnDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
202 | ast::ModuleItem::TraitDef(it) => self.items.push(ModuleItem::new(it)?), | 252 | ast::ModuleItem::TraitDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
203 | ast::ModuleItem::TypeDef(it) => self.items.push(ModuleItem::new(it)?), | 253 | ast::ModuleItem::TypeDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
204 | ast::ModuleItem::ImplItem(_) => { | 254 | ast::ModuleItem::ImplItem(_) => { |
205 | // impls don't define items | 255 | // impls don't define items |
206 | } | 256 | } |
207 | ast::ModuleItem::UseItem(it) => self.add_use_item(it), | 257 | ast::ModuleItem::UseItem(it) => self.add_use_item(file_items, it), |
208 | ast::ModuleItem::ExternCrateItem(_) => { | 258 | ast::ModuleItem::ExternCrateItem(_) => { |
209 | // TODO | 259 | // TODO |
210 | } | 260 | } |
211 | ast::ModuleItem::ConstDef(it) => self.items.push(ModuleItem::new(it)?), | 261 | ast::ModuleItem::ConstDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
212 | ast::ModuleItem::StaticDef(it) => self.items.push(ModuleItem::new(it)?), | 262 | ast::ModuleItem::StaticDef(it) => self.items.push(ModuleItem::new(file_items, it)?), |
213 | ast::ModuleItem::Module(it) => self.items.push(ModuleItem::new(it)?), | 263 | ast::ModuleItem::Module(it) => self.items.push(ModuleItem::new(file_items, it)?), |
214 | } | 264 | } |
215 | Some(()) | 265 | Some(()) |
216 | } | 266 | } |
217 | 267 | ||
218 | fn add_use_item(&mut self, item: ast::UseItem) { | 268 | fn add_use_item(&mut self, file_items: &FileItems, item: ast::UseItem) { |
219 | Path::expand_use_item(item, |path, ptr| { | 269 | let file_item_id = file_items.id_of(item.syntax()); |
220 | let kind = match ptr { | 270 | let start_offset = item.syntax().range().start(); |
271 | Path::expand_use_item(item, |path, range| { | ||
272 | let kind = match range { | ||
221 | None => ImportKind::Glob, | 273 | None => ImportKind::Glob, |
222 | Some(ptr) => ImportKind::Named(ptr), | 274 | Some(range) => ImportKind::Named(NamedImport { |
275 | file_item_id, | ||
276 | relative_range: range - start_offset, | ||
277 | }), | ||
223 | }; | 278 | }; |
224 | self.imports.push(Import { kind, path }) | 279 | self.imports.push(Import { kind, path }) |
225 | }) | 280 | }) |
@@ -227,13 +282,13 @@ impl InputModuleItems { | |||
227 | } | 282 | } |
228 | 283 | ||
229 | impl ModuleItem { | 284 | impl ModuleItem { |
230 | fn new<'a>(item: impl ast::NameOwner<'a>) -> Option<ModuleItem> { | 285 | fn new<'a>(file_items: &FileItems, item: impl ast::NameOwner<'a>) -> Option<ModuleItem> { |
231 | let name = item.name()?.text(); | 286 | let name = item.name()?.text(); |
232 | let ptr = LocalSyntaxPtr::new(item.syntax()); | ||
233 | let kind = item.syntax().kind(); | 287 | let kind = item.syntax().kind(); |
234 | let vis = Vis::Other; | 288 | let vis = Vis::Other; |
289 | let id = file_items.id_of(item.syntax()); | ||
235 | let res = ModuleItem { | 290 | let res = ModuleItem { |
236 | ptr, | 291 | id, |
237 | name, | 292 | name, |
238 | kind, | 293 | kind, |
239 | vis, | 294 | vis, |
@@ -273,12 +328,12 @@ where | |||
273 | 328 | ||
274 | for import in input.imports.iter() { | 329 | for import in input.imports.iter() { |
275 | if let Some(name) = import.path.segments.iter().last() { | 330 | if let Some(name) = import.path.segments.iter().last() { |
276 | if let ImportKind::Named(ptr) = import.kind { | 331 | if let ImportKind::Named(import) = import.kind { |
277 | module_items.items.insert( | 332 | module_items.items.insert( |
278 | name.clone(), | 333 | name.clone(), |
279 | Resolution { | 334 | Resolution { |
280 | def_id: None, | 335 | def_id: None, |
281 | import_name: Some(ptr), | 336 | import: Some(import), |
282 | }, | 337 | }, |
283 | ); | 338 | ); |
284 | } | 339 | } |
@@ -290,12 +345,14 @@ where | |||
290 | // handle submodules separatelly | 345 | // handle submodules separatelly |
291 | continue; | 346 | continue; |
292 | } | 347 | } |
293 | let ptr = item.ptr.into_global(file_id); | 348 | let def_loc = DefLoc::Item { |
294 | let def_loc = DefLoc::Item { ptr }; | 349 | file_id, |
350 | id: item.id, | ||
351 | }; | ||
295 | let def_id = self.db.id_maps().def_id(def_loc); | 352 | let def_id = self.db.id_maps().def_id(def_loc); |
296 | let resolution = Resolution { | 353 | let resolution = Resolution { |
297 | def_id: Some(def_id), | 354 | def_id: Some(def_id), |
298 | import_name: None, | 355 | import: None, |
299 | }; | 356 | }; |
300 | module_items.items.insert(item.name.clone(), resolution); | 357 | module_items.items.insert(item.name.clone(), resolution); |
301 | } | 358 | } |
@@ -308,7 +365,7 @@ where | |||
308 | let def_id = self.db.id_maps().def_id(def_loc); | 365 | let def_id = self.db.id_maps().def_id(def_loc); |
309 | let resolution = Resolution { | 366 | let resolution = Resolution { |
310 | def_id: Some(def_id), | 367 | def_id: Some(def_id), |
311 | import_name: None, | 368 | import: None, |
312 | }; | 369 | }; |
313 | module_items.items.insert(name, resolution); | 370 | module_items.items.insert(name, resolution); |
314 | } | 371 | } |
@@ -362,7 +419,7 @@ where | |||
362 | self.update(module_id, |items| { | 419 | self.update(module_id, |items| { |
363 | let res = Resolution { | 420 | let res = Resolution { |
364 | def_id: Some(def_id), | 421 | def_id: Some(def_id), |
365 | import_name: Some(ptr), | 422 | import: Some(ptr), |
366 | }; | 423 | }; |
367 | items.items.insert(name.clone(), res); | 424 | items.items.insert(name.clone(), res); |
368 | }) | 425 | }) |
@@ -473,10 +530,11 @@ mod tests { | |||
473 | let events = db.log_executed(|| { | 530 | let events = db.log_executed(|| { |
474 | db._item_map(source_root).unwrap(); | 531 | db._item_map(source_root).unwrap(); |
475 | }); | 532 | }); |
476 | // assert!( | 533 | assert!( |
477 | // !format!("{:?}", events).contains("_item_map"), | 534 | !format!("{:?}", events).contains("_item_map"), |
478 | // "{:#?}", events | 535 | "{:#?}", |
479 | // ) | 536 | events |
537 | ) | ||
480 | } | 538 | } |
481 | } | 539 | } |
482 | } | 540 | } |
diff --git a/crates/ra_analysis/src/descriptors/path.rs b/crates/ra_analysis/src/descriptors/path.rs index 99fca18b1..8279daf4b 100644 --- a/crates/ra_analysis/src/descriptors/path.rs +++ b/crates/ra_analysis/src/descriptors/path.rs | |||
@@ -1,6 +1,4 @@ | |||
1 | use ra_syntax::{SmolStr, ast, AstNode}; | 1 | use ra_syntax::{SmolStr, ast, AstNode, TextRange}; |
2 | |||
3 | use crate::syntax_ptr::LocalSyntaxPtr; | ||
4 | 2 | ||
5 | #[derive(Debug, Clone, PartialEq, Eq)] | 3 | #[derive(Debug, Clone, PartialEq, Eq)] |
6 | pub(crate) struct Path { | 4 | pub(crate) struct Path { |
@@ -18,10 +16,7 @@ pub(crate) enum PathKind { | |||
18 | 16 | ||
19 | impl Path { | 17 | impl Path { |
20 | /// Calls `cb` with all paths, represented by this use item. | 18 | /// Calls `cb` with all paths, represented by this use item. |
21 | pub(crate) fn expand_use_item( | 19 | pub(crate) fn expand_use_item(item: ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) { |
22 | item: ast::UseItem, | ||
23 | mut cb: impl FnMut(Path, Option<LocalSyntaxPtr>), | ||
24 | ) { | ||
25 | if let Some(tree) = item.use_tree() { | 20 | if let Some(tree) = item.use_tree() { |
26 | expand_use_tree(None, tree, &mut cb); | 21 | expand_use_tree(None, tree, &mut cb); |
27 | } | 22 | } |
@@ -77,7 +72,7 @@ impl Path { | |||
77 | fn expand_use_tree( | 72 | fn expand_use_tree( |
78 | prefix: Option<Path>, | 73 | prefix: Option<Path>, |
79 | tree: ast::UseTree, | 74 | tree: ast::UseTree, |
80 | cb: &mut impl FnMut(Path, Option<LocalSyntaxPtr>), | 75 | cb: &mut impl FnMut(Path, Option<TextRange>), |
81 | ) { | 76 | ) { |
82 | if let Some(use_tree_list) = tree.use_tree_list() { | 77 | if let Some(use_tree_list) = tree.use_tree_list() { |
83 | let prefix = match tree.path() { | 78 | let prefix = match tree.path() { |
@@ -93,13 +88,13 @@ fn expand_use_tree( | |||
93 | } else { | 88 | } else { |
94 | if let Some(ast_path) = tree.path() { | 89 | if let Some(ast_path) = tree.path() { |
95 | if let Some(path) = convert_path(prefix, ast_path) { | 90 | if let Some(path) = convert_path(prefix, ast_path) { |
96 | let ptr = if tree.has_star() { | 91 | let range = if tree.has_star() { |
97 | None | 92 | None |
98 | } else { | 93 | } else { |
99 | let ptr = LocalSyntaxPtr::new(ast_path.segment().unwrap().syntax()); | 94 | let range = ast_path.segment().unwrap().syntax().range(); |
100 | Some(ptr) | 95 | Some(range) |
101 | }; | 96 | }; |
102 | cb(path, ptr) | 97 | cb(path, range) |
103 | } | 98 | } |
104 | } | 99 | } |
105 | } | 100 | } |
diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs index e4b55f9b0..c7c799a91 100644 --- a/crates/ra_analysis/src/loc2id.rs +++ b/crates/ra_analysis/src/loc2id.rs | |||
@@ -8,6 +8,8 @@ use std::{ | |||
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | FileId, | ||
12 | descriptors::FileItemId, | ||
11 | descriptors::module::ModuleId, | 13 | descriptors::module::ModuleId, |
12 | syntax_ptr::SyntaxPtr, | 14 | syntax_ptr::SyntaxPtr, |
13 | input::SourceRootId, | 15 | input::SourceRootId, |
@@ -102,7 +104,8 @@ pub(crate) enum DefLoc { | |||
102 | source_root: SourceRootId, | 104 | source_root: SourceRootId, |
103 | }, | 105 | }, |
104 | Item { | 106 | Item { |
105 | ptr: SyntaxPtr, | 107 | file_id: FileId, |
108 | id: FileItemId, | ||
106 | }, | 109 | }, |
107 | } | 110 | } |
108 | 111 | ||
diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs index 194b94584..e45934ce0 100644 --- a/crates/ra_analysis/src/syntax_ptr.rs +++ b/crates/ra_analysis/src/syntax_ptr.rs | |||
@@ -62,11 +62,6 @@ impl LocalSyntaxPtr { | |||
62 | local: self, | 62 | local: self, |
63 | } | 63 | } |
64 | } | 64 | } |
65 | |||
66 | // Seems unfortunate to expose | ||
67 | pub(crate) fn range(self) -> TextRange { | ||
68 | self.range | ||
69 | } | ||
70 | } | 65 | } |
71 | 66 | ||
72 | #[test] | 67 | #[test] |