diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/raw.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 143 |
1 files changed, 70 insertions, 73 deletions
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index f8ba398ec..0936229ac 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -4,7 +4,6 @@ use std::{ | |||
4 | }; | 4 | }; |
5 | 5 | ||
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | use ra_db::FileId; | ||
8 | use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap}; | 7 | use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap}; |
9 | use ra_syntax::{ | 8 | use ra_syntax::{ |
10 | AstNode, SourceFile, AstPtr, TreeArc, | 9 | AstNode, SourceFile, AstPtr, TreeArc, |
@@ -13,9 +12,13 @@ use ra_syntax::{ | |||
13 | 12 | ||
14 | use crate::{ | 13 | use crate::{ |
15 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, | 14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, |
16 | ids::{SourceFileItemId, SourceFileItems}, | 15 | AstIdMap, FileAstId, |
17 | }; | 16 | }; |
18 | 17 | ||
18 | /// `RawItems` is a set of top-level items in a file (except for impls). | ||
19 | /// | ||
20 | /// It is the input to name resolution algorithm. `RawItems` are not invalidated | ||
21 | /// on most edits. | ||
19 | #[derive(Debug, Default, PartialEq, Eq)] | 22 | #[derive(Debug, Default, PartialEq, Eq)] |
20 | pub struct RawItems { | 23 | pub struct RawItems { |
21 | modules: Arena<Module, ModuleData>, | 24 | modules: Arena<Module, ModuleData>, |
@@ -32,11 +35,11 @@ pub struct ImportSourceMap { | |||
32 | } | 35 | } |
33 | 36 | ||
34 | impl ImportSourceMap { | 37 | impl ImportSourceMap { |
35 | pub(crate) fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { | 38 | fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { |
36 | self.map.insert(import, AstPtr::new(segment)) | 39 | self.map.insert(import, AstPtr::new(segment)) |
37 | } | 40 | } |
38 | 41 | ||
39 | pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> { | 42 | pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> { |
40 | let file = match source { | 43 | let file = match source { |
41 | ModuleSource::SourceFile(file) => &*file, | 44 | ModuleSource::SourceFile(file) => &*file, |
42 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), | 45 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), |
@@ -47,40 +50,27 @@ impl ImportSourceMap { | |||
47 | } | 50 | } |
48 | 51 | ||
49 | impl RawItems { | 52 | impl RawItems { |
50 | pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: FileId) -> Arc<RawItems> { | 53 | pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: HirFileId) -> Arc<RawItems> { |
51 | db.raw_items_with_source_map(file_id).0 | 54 | db.raw_items_with_source_map(file_id).0 |
52 | } | 55 | } |
53 | 56 | ||
54 | pub(crate) fn raw_items_with_source_map_query( | 57 | pub(crate) fn raw_items_with_source_map_query( |
55 | db: &impl DefDatabase, | 58 | db: &impl DefDatabase, |
56 | file_id: FileId, | 59 | file_id: HirFileId, |
57 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | 60 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { |
58 | let mut collector = RawItemsCollector { | 61 | let mut collector = RawItemsCollector { |
59 | raw_items: RawItems::default(), | 62 | raw_items: RawItems::default(), |
60 | source_file_items: db.file_items(file_id.into()), | 63 | source_ast_id_map: db.ast_id_map(file_id.into()), |
61 | source_map: ImportSourceMap::default(), | 64 | source_map: ImportSourceMap::default(), |
62 | }; | 65 | }; |
63 | let source_file = db.parse(file_id); | 66 | let source_file = db.hir_parse(file_id); |
64 | collector.process_module(None, &*source_file); | 67 | collector.process_module(None, &*source_file); |
65 | (Arc::new(collector.raw_items), Arc::new(collector.source_map)) | 68 | (Arc::new(collector.raw_items), Arc::new(collector.source_map)) |
66 | } | 69 | } |
67 | 70 | ||
68 | pub(crate) fn items(&self) -> &[RawItem] { | 71 | pub(super) fn items(&self) -> &[RawItem] { |
69 | &self.items | 72 | &self.items |
70 | } | 73 | } |
71 | |||
72 | // We can't use queries during name resolution for fear of cycles, so this | ||
73 | // is a query-less variant of the above function. | ||
74 | pub(crate) fn from_source_file(source_file: &SourceFile, file_id: HirFileId) -> RawItems { | ||
75 | let source_file_items = SourceFileItems::from_source_file(source_file, file_id); | ||
76 | let mut collector = RawItemsCollector { | ||
77 | raw_items: RawItems::default(), | ||
78 | source_file_items: Arc::new(source_file_items), | ||
79 | source_map: ImportSourceMap::default(), | ||
80 | }; | ||
81 | collector.process_module(None, &*source_file); | ||
82 | collector.raw_items | ||
83 | } | ||
84 | } | 74 | } |
85 | 75 | ||
86 | impl Index<Module> for RawItems { | 76 | impl Index<Module> for RawItems { |
@@ -112,7 +102,7 @@ impl Index<Macro> for RawItems { | |||
112 | } | 102 | } |
113 | 103 | ||
114 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 104 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
115 | pub(crate) enum RawItem { | 105 | pub(super) enum RawItem { |
116 | Module(Module), | 106 | Module(Module), |
117 | Import(ImportId), | 107 | Import(ImportId), |
118 | Def(Def), | 108 | Def(Def), |
@@ -120,13 +110,13 @@ pub(crate) enum RawItem { | |||
120 | } | 110 | } |
121 | 111 | ||
122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 112 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
123 | pub(crate) struct Module(RawId); | 113 | pub(super) struct Module(RawId); |
124 | impl_arena_id!(Module); | 114 | impl_arena_id!(Module); |
125 | 115 | ||
126 | #[derive(Debug, PartialEq, Eq)] | 116 | #[derive(Debug, PartialEq, Eq)] |
127 | pub(crate) enum ModuleData { | 117 | pub(super) enum ModuleData { |
128 | Declaration { name: Name, source_item_id: SourceFileItemId }, | 118 | Declaration { name: Name, ast_id: FileAstId<ast::Module> }, |
129 | Definition { name: Name, source_item_id: SourceFileItemId, items: Vec<RawItem> }, | 119 | Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, |
130 | } | 120 | } |
131 | 121 | ||
132 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -135,51 +125,49 @@ impl_arena_id!(ImportId); | |||
135 | 125 | ||
136 | #[derive(Debug, Clone, PartialEq, Eq)] | 126 | #[derive(Debug, Clone, PartialEq, Eq)] |
137 | pub struct ImportData { | 127 | pub struct ImportData { |
138 | pub(crate) path: Path, | 128 | pub(super) path: Path, |
139 | pub(crate) alias: Option<Name>, | 129 | pub(super) alias: Option<Name>, |
140 | pub(crate) is_glob: bool, | 130 | pub(super) is_glob: bool, |
141 | pub(crate) is_prelude: bool, | 131 | pub(super) is_prelude: bool, |
142 | pub(crate) is_extern_crate: bool, | 132 | pub(super) is_extern_crate: bool, |
143 | } | 133 | } |
144 | 134 | ||
145 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 135 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
146 | pub(crate) struct Def(RawId); | 136 | pub(super) struct Def(RawId); |
147 | impl_arena_id!(Def); | 137 | impl_arena_id!(Def); |
148 | 138 | ||
149 | #[derive(Debug, PartialEq, Eq)] | 139 | #[derive(Debug, PartialEq, Eq)] |
150 | pub(crate) struct DefData { | 140 | pub(super) struct DefData { |
151 | pub(crate) source_item_id: SourceFileItemId, | 141 | pub(super) name: Name, |
152 | pub(crate) name: Name, | 142 | pub(super) kind: DefKind, |
153 | pub(crate) kind: DefKind, | ||
154 | } | 143 | } |
155 | 144 | ||
156 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 145 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
157 | pub(crate) enum DefKind { | 146 | pub(super) enum DefKind { |
158 | Function, | 147 | Function(FileAstId<ast::FnDef>), |
159 | Struct, | 148 | Struct(FileAstId<ast::StructDef>), |
160 | Enum, | 149 | Enum(FileAstId<ast::EnumDef>), |
161 | Const, | 150 | Const(FileAstId<ast::ConstDef>), |
162 | Static, | 151 | Static(FileAstId<ast::StaticDef>), |
163 | Trait, | 152 | Trait(FileAstId<ast::TraitDef>), |
164 | TypeAlias, | 153 | TypeAlias(FileAstId<ast::TypeAliasDef>), |
165 | } | 154 | } |
166 | 155 | ||
167 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 156 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
168 | pub(crate) struct Macro(RawId); | 157 | pub(super) struct Macro(RawId); |
169 | impl_arena_id!(Macro); | 158 | impl_arena_id!(Macro); |
170 | 159 | ||
171 | #[derive(Debug, PartialEq, Eq)] | 160 | #[derive(Debug, PartialEq, Eq)] |
172 | pub(crate) struct MacroData { | 161 | pub(super) struct MacroData { |
173 | pub(crate) source_item_id: SourceFileItemId, | 162 | pub(super) ast_id: FileAstId<ast::MacroCall>, |
174 | pub(crate) path: Path, | 163 | pub(super) path: Path, |
175 | pub(crate) name: Option<Name>, | 164 | pub(super) name: Option<Name>, |
176 | pub(crate) arg: tt::Subtree, | 165 | pub(super) export: bool, |
177 | pub(crate) export: bool, | ||
178 | } | 166 | } |
179 | 167 | ||
180 | struct RawItemsCollector { | 168 | struct RawItemsCollector { |
181 | raw_items: RawItems, | 169 | raw_items: RawItems, |
182 | source_file_items: Arc<SourceFileItems>, | 170 | source_ast_id_map: Arc<AstIdMap>, |
183 | source_map: ImportSourceMap, | 171 | source_map: ImportSourceMap, |
184 | } | 172 | } |
185 | 173 | ||
@@ -211,18 +199,31 @@ impl RawItemsCollector { | |||
211 | // impls don't participate in name resolution | 199 | // impls don't participate in name resolution |
212 | return; | 200 | return; |
213 | } | 201 | } |
214 | ast::ModuleItemKind::StructDef(it) => (DefKind::Struct, it.name()), | 202 | ast::ModuleItemKind::StructDef(it) => { |
215 | ast::ModuleItemKind::EnumDef(it) => (DefKind::Enum, it.name()), | 203 | (DefKind::Struct(self.source_ast_id_map.ast_id(it)), it.name()) |
216 | ast::ModuleItemKind::FnDef(it) => (DefKind::Function, it.name()), | 204 | } |
217 | ast::ModuleItemKind::TraitDef(it) => (DefKind::Trait, it.name()), | 205 | ast::ModuleItemKind::EnumDef(it) => { |
218 | ast::ModuleItemKind::TypeAliasDef(it) => (DefKind::TypeAlias, it.name()), | 206 | (DefKind::Enum(self.source_ast_id_map.ast_id(it)), it.name()) |
219 | ast::ModuleItemKind::ConstDef(it) => (DefKind::Const, it.name()), | 207 | } |
220 | ast::ModuleItemKind::StaticDef(it) => (DefKind::Static, it.name()), | 208 | ast::ModuleItemKind::FnDef(it) => { |
209 | (DefKind::Function(self.source_ast_id_map.ast_id(it)), it.name()) | ||
210 | } | ||
211 | ast::ModuleItemKind::TraitDef(it) => { | ||
212 | (DefKind::Trait(self.source_ast_id_map.ast_id(it)), it.name()) | ||
213 | } | ||
214 | ast::ModuleItemKind::TypeAliasDef(it) => { | ||
215 | (DefKind::TypeAlias(self.source_ast_id_map.ast_id(it)), it.name()) | ||
216 | } | ||
217 | ast::ModuleItemKind::ConstDef(it) => { | ||
218 | (DefKind::Const(self.source_ast_id_map.ast_id(it)), it.name()) | ||
219 | } | ||
220 | ast::ModuleItemKind::StaticDef(it) => { | ||
221 | (DefKind::Static(self.source_ast_id_map.ast_id(it)), it.name()) | ||
222 | } | ||
221 | }; | 223 | }; |
222 | if let Some(name) = name { | 224 | if let Some(name) = name { |
223 | let name = name.as_name(); | 225 | let name = name.as_name(); |
224 | let source_item_id = self.source_file_items.id_of_unchecked(item.syntax()); | 226 | let def = self.raw_items.defs.alloc(DefData { name, kind }); |
225 | let def = self.raw_items.defs.alloc(DefData { name, kind, source_item_id }); | ||
226 | self.push_item(current_module, RawItem::Def(def)) | 227 | self.push_item(current_module, RawItem::Def(def)) |
227 | } | 228 | } |
228 | } | 229 | } |
@@ -232,10 +233,9 @@ impl RawItemsCollector { | |||
232 | Some(it) => it.as_name(), | 233 | Some(it) => it.as_name(), |
233 | None => return, | 234 | None => return, |
234 | }; | 235 | }; |
235 | let source_item_id = self.source_file_items.id_of_unchecked(module.syntax()); | 236 | let ast_id = self.source_ast_id_map.ast_id(module); |
236 | if module.has_semi() { | 237 | if module.has_semi() { |
237 | let item = | 238 | let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); |
238 | self.raw_items.modules.alloc(ModuleData::Declaration { name, source_item_id }); | ||
239 | self.push_item(current_module, RawItem::Module(item)); | 239 | self.push_item(current_module, RawItem::Module(item)); |
240 | return; | 240 | return; |
241 | } | 241 | } |
@@ -243,7 +243,7 @@ impl RawItemsCollector { | |||
243 | if let Some(item_list) = module.item_list() { | 243 | if let Some(item_list) = module.item_list() { |
244 | let item = self.raw_items.modules.alloc(ModuleData::Definition { | 244 | let item = self.raw_items.modules.alloc(ModuleData::Definition { |
245 | name, | 245 | name, |
246 | source_item_id, | 246 | ast_id, |
247 | items: Vec::new(), | 247 | items: Vec::new(), |
248 | }); | 248 | }); |
249 | self.process_module(Some(item), item_list); | 249 | self.process_module(Some(item), item_list); |
@@ -291,18 +291,15 @@ impl RawItemsCollector { | |||
291 | } | 291 | } |
292 | 292 | ||
293 | fn add_macro(&mut self, current_module: Option<Module>, m: &ast::MacroCall) { | 293 | fn add_macro(&mut self, current_module: Option<Module>, m: &ast::MacroCall) { |
294 | let (path, arg) = match ( | 294 | let path = match m.path().and_then(Path::from_ast) { |
295 | m.path().and_then(Path::from_ast), | 295 | Some(it) => it, |
296 | m.token_tree().and_then(mbe::ast_to_token_tree), | ||
297 | ) { | ||
298 | (Some(path), Some((token_tree, _token_map))) => (path, token_tree), | ||
299 | _ => return, | 296 | _ => return, |
300 | }; | 297 | }; |
301 | 298 | ||
302 | let name = m.name().map(|it| it.as_name()); | 299 | let name = m.name().map(|it| it.as_name()); |
303 | let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); | 300 | let ast_id = self.source_ast_id_map.ast_id(m); |
304 | let export = m.has_atom_attr("macro_export"); | 301 | let export = m.has_atom_attr("macro_export"); |
305 | let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, arg, name, export }); | 302 | let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); |
306 | self.push_item(current_module, RawItem::Macro(m)); | 303 | self.push_item(current_module, RawItem::Macro(m)); |
307 | } | 304 | } |
308 | 305 | ||