aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres/raw.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres/raw.rs')
-rw-r--r--crates/ra_hir/src/nameres/raw.rs143
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
6use test_utils::tested_by; 6use test_utils::tested_by;
7use ra_db::FileId;
8use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap}; 7use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap};
9use ra_syntax::{ 8use ra_syntax::{
10 AstNode, SourceFile, AstPtr, TreeArc, 9 AstNode, SourceFile, AstPtr, TreeArc,
@@ -13,9 +12,13 @@ use ra_syntax::{
13 12
14use crate::{ 13use 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)]
20pub struct RawItems { 23pub struct RawItems {
21 modules: Arena<Module, ModuleData>, 24 modules: Arena<Module, ModuleData>,
@@ -32,11 +35,11 @@ pub struct ImportSourceMap {
32} 35}
33 36
34impl ImportSourceMap { 37impl 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
49impl RawItems { 52impl 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
86impl Index<Module> for RawItems { 76impl 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)]
115pub(crate) enum RawItem { 105pub(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)]
123pub(crate) struct Module(RawId); 113pub(super) struct Module(RawId);
124impl_arena_id!(Module); 114impl_arena_id!(Module);
125 115
126#[derive(Debug, PartialEq, Eq)] 116#[derive(Debug, PartialEq, Eq)]
127pub(crate) enum ModuleData { 117pub(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)]
137pub struct ImportData { 127pub 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)]
146pub(crate) struct Def(RawId); 136pub(super) struct Def(RawId);
147impl_arena_id!(Def); 137impl_arena_id!(Def);
148 138
149#[derive(Debug, PartialEq, Eq)] 139#[derive(Debug, PartialEq, Eq)]
150pub(crate) struct DefData { 140pub(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)]
157pub(crate) enum DefKind { 146pub(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)]
168pub(crate) struct Macro(RawId); 157pub(super) struct Macro(RawId);
169impl_arena_id!(Macro); 158impl_arena_id!(Macro);
170 159
171#[derive(Debug, PartialEq, Eq)] 160#[derive(Debug, PartialEq, Eq)]
172pub(crate) struct MacroData { 161pub(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
180struct RawItemsCollector { 168struct 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