aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-15 18:16:43 +0100
committerJonas Schievink <[email protected]>2020-06-24 15:53:16 +0100
commit0e2602f75e17b35472637c8ebd8e6e436a5f2af4 (patch)
tree959a856badde77a0f554f66320a0ec02ffa90617 /crates/ra_hir_def
parent7054e89d187287c0547ef43961bf4969aba57dd6 (diff)
Remove raw item query
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/db.rs5
-rw-r--r--crates/ra_hir_def/src/nameres.rs1
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs483
3 files changed, 1 insertions, 488 deletions
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index c4c9e10a3..9c3ede2d7 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -16,7 +16,7 @@ use crate::{
16 import_map::ImportMap, 16 import_map::ImportMap,
17 item_tree::ItemTree, 17 item_tree::ItemTree,
18 lang_item::{LangItemTarget, LangItems}, 18 lang_item::{LangItemTarget, LangItems},
19 nameres::{raw::RawItems, CrateDefMap}, 19 nameres::CrateDefMap,
20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
21 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 21 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
22 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 22 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
@@ -46,9 +46,6 @@ pub trait InternDatabase: SourceDatabase {
46 46
47#[salsa::query_group(DefDatabaseStorage)] 47#[salsa::query_group(DefDatabaseStorage)]
48pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { 48pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
49 #[salsa::invoke(RawItems::raw_items_query)]
50 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
51
52 #[salsa::invoke(ItemTree::item_tree_query)] 49 #[salsa::invoke(ItemTree::item_tree_query)]
53 fn item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>; 50 fn item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
54 51
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 060273db4..b279bdeef 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -47,7 +47,6 @@
47//! path and, upon success, we run macro expansion and "collect module" phase on 47//! path and, upon success, we run macro expansion and "collect module" phase on
48//! the result 48//! the result
49 49
50pub(crate) mod raw;
51mod collector; 50mod collector;
52mod mod_resolution; 51mod mod_resolution;
53mod path_resolution; 52mod path_resolution;
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
deleted file mode 100644
index d83a5b2b5..000000000
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ /dev/null
@@ -1,483 +0,0 @@
1//! Lowers syntax tree of a rust file into a raw representation of containing
2//! items, *without* attaching them to a module structure.
3//!
4//! That is, raw items don't have semantics, just as syntax, but, unlike syntax,
5//! they don't change with trivial source code edits, making them a great tool
6//! for building salsa recomputation firewalls.
7
8use std::{ops::Index, sync::Arc};
9
10use hir_expand::{
11 ast_id_map::AstIdMap,
12 hygiene::Hygiene,
13 name::{AsName, Name},
14};
15use ra_arena::{Arena, Idx};
16use ra_prof::profile;
17use ra_syntax::{
18 ast::{self, AttrsOwner, NameOwner, VisibilityOwner},
19 AstNode,
20};
21use test_utils::mark;
22
23use crate::{
24 attr::Attrs,
25 db::DefDatabase,
26 path::{ImportAlias, ModPath},
27 visibility::RawVisibility,
28 FileAstId, HirFileId, InFile,
29};
30
31/// `RawItems` is a set of top-level items in a file (except for impls).
32///
33/// It is the input to name resolution algorithm. `RawItems` are not invalidated
34/// on most edits.
35#[derive(Debug, Default, PartialEq, Eq)]
36pub struct RawItems {
37 modules: Arena<ModuleData>,
38 imports: Arena<ImportData>,
39 defs: Arena<DefData>,
40 macros: Arena<MacroData>,
41 impls: Arena<ImplData>,
42 /// items for top-level module
43 items: Vec<RawItem>,
44}
45
46impl RawItems {
47 pub(crate) fn raw_items_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<RawItems> {
48 let _p = profile("raw_items_query");
49 db.item_tree(file_id);
50 let mut collector = RawItemsCollector {
51 raw_items: RawItems::default(),
52 source_ast_id_map: db.ast_id_map(file_id),
53 file_id,
54 hygiene: Hygiene::new(db.upcast(), file_id),
55 };
56 if let Some(node) = db.parse_or_expand(file_id) {
57 if let Some(source_file) = ast::SourceFile::cast(node.clone()) {
58 collector.process_module(None, source_file);
59 } else if let Some(item_list) = ast::MacroItems::cast(node) {
60 collector.process_module(None, item_list);
61 }
62 }
63 let raw_items = collector.raw_items;
64 Arc::new(raw_items)
65 }
66
67 pub(super) fn items(&self) -> &[RawItem] {
68 &self.items
69 }
70}
71
72impl Index<Idx<ModuleData>> for RawItems {
73 type Output = ModuleData;
74 fn index(&self, idx: Idx<ModuleData>) -> &ModuleData {
75 &self.modules[idx]
76 }
77}
78
79impl Index<Import> for RawItems {
80 type Output = ImportData;
81 fn index(&self, idx: Import) -> &ImportData {
82 &self.imports[idx]
83 }
84}
85
86impl Index<Idx<DefData>> for RawItems {
87 type Output = DefData;
88 fn index(&self, idx: Idx<DefData>) -> &DefData {
89 &self.defs[idx]
90 }
91}
92
93impl Index<Idx<MacroData>> for RawItems {
94 type Output = MacroData;
95 fn index(&self, idx: Idx<MacroData>) -> &MacroData {
96 &self.macros[idx]
97 }
98}
99
100impl Index<Idx<ImplData>> for RawItems {
101 type Output = ImplData;
102 fn index(&self, idx: Idx<ImplData>) -> &ImplData {
103 &self.impls[idx]
104 }
105}
106
107#[derive(Debug, PartialEq, Eq, Clone)]
108pub(super) struct RawItem {
109 pub(super) attrs: Attrs,
110 pub(super) kind: RawItemKind,
111}
112
113#[derive(Debug, PartialEq, Eq, Clone, Copy)]
114pub(super) enum RawItemKind {
115 Module(Idx<ModuleData>),
116 Import(Import),
117 Def(Idx<DefData>),
118 Macro(Idx<MacroData>),
119 Impl(Idx<ImplData>),
120}
121
122#[derive(Debug, PartialEq, Eq)]
123pub(super) enum ModuleData {
124 Declaration {
125 name: Name,
126 visibility: RawVisibility,
127 ast_id: FileAstId<ast::Module>,
128 },
129 Definition {
130 name: Name,
131 visibility: RawVisibility,
132 ast_id: FileAstId<ast::Module>,
133 items: Vec<RawItem>,
134 },
135}
136
137pub(crate) type Import = Idx<ImportData>;
138
139#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct ImportData {
141 pub(super) path: ModPath,
142 pub(super) alias: Option<ImportAlias>,
143 pub(super) is_glob: bool,
144 pub(super) is_prelude: bool,
145 pub(super) is_extern_crate: bool,
146 pub(super) is_macro_use: bool,
147 pub(super) visibility: RawVisibility,
148}
149
150// type Def = Idx<DefData>;
151
152#[derive(Debug, PartialEq, Eq)]
153pub(super) struct DefData {
154 pub(super) name: Name,
155 pub(super) kind: DefKind,
156 pub(super) visibility: RawVisibility,
157}
158
159#[derive(Debug, PartialEq, Eq, Clone, Copy)]
160pub(super) enum StructDefKind {
161 Record,
162 Tuple,
163 Unit,
164}
165
166#[derive(Debug, PartialEq, Eq, Clone, Copy)]
167pub(super) enum DefKind {
168 Function(FileAstId<ast::FnDef>),
169 Struct(FileAstId<ast::StructDef>, StructDefKind),
170 Union(FileAstId<ast::UnionDef>),
171 Enum(FileAstId<ast::EnumDef>),
172 Const(FileAstId<ast::ConstDef>),
173 Static(FileAstId<ast::StaticDef>),
174 Trait(FileAstId<ast::TraitDef>),
175 TypeAlias(FileAstId<ast::TypeAliasDef>),
176}
177
178impl DefKind {
179 pub fn ast_id(self) -> FileAstId<ast::ModuleItem> {
180 match self {
181 DefKind::Function(it) => it.upcast(),
182 DefKind::Struct(it, _) => it.upcast(),
183 DefKind::Union(it) => it.upcast(),
184 DefKind::Enum(it) => it.upcast(),
185 DefKind::Const(it) => it.upcast(),
186 DefKind::Static(it) => it.upcast(),
187 DefKind::Trait(it) => it.upcast(),
188 DefKind::TypeAlias(it) => it.upcast(),
189 }
190 }
191}
192
193#[derive(Debug, PartialEq, Eq)]
194pub(super) struct MacroData {
195 pub(super) ast_id: FileAstId<ast::MacroCall>,
196 pub(super) path: ModPath,
197 pub(super) name: Option<Name>,
198 pub(super) export: bool,
199 pub(super) local_inner: bool,
200 pub(super) builtin: bool,
201}
202
203#[derive(Debug, PartialEq, Eq)]
204pub(super) struct ImplData {
205 pub(super) ast_id: FileAstId<ast::ImplDef>,
206}
207
208struct RawItemsCollector {
209 raw_items: RawItems,
210 source_ast_id_map: Arc<AstIdMap>,
211 file_id: HirFileId,
212 hygiene: Hygiene,
213}
214
215impl RawItemsCollector {
216 fn process_module(
217 &mut self,
218 current_module: Option<Idx<ModuleData>>,
219 body: impl ast::ModuleItemOwner,
220 ) {
221 for item in body.items() {
222 self.add_item(current_module, item)
223 }
224 }
225
226 fn add_item(&mut self, current_module: Option<Idx<ModuleData>>, item: ast::ModuleItem) {
227 let attrs = self.parse_attrs(&item);
228 let visibility = RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene);
229 let (kind, name) = match item {
230 ast::ModuleItem::Module(module) => {
231 self.add_module(current_module, module);
232 return;
233 }
234 ast::ModuleItem::UseItem(use_item) => {
235 self.add_use_item(current_module, use_item);
236 return;
237 }
238 ast::ModuleItem::ExternCrateItem(extern_crate) => {
239 self.add_extern_crate_item(current_module, extern_crate);
240 return;
241 }
242 ast::ModuleItem::ImplDef(it) => {
243 self.add_impl(current_module, it);
244 return;
245 }
246 ast::ModuleItem::StructDef(it) => {
247 let kind = match it.kind() {
248 ast::StructKind::Record(_) => StructDefKind::Record,
249 ast::StructKind::Tuple(_) => StructDefKind::Tuple,
250 ast::StructKind::Unit => StructDefKind::Unit,
251 };
252 let id = self.source_ast_id_map.ast_id(&it);
253 let name = it.name();
254 (DefKind::Struct(id, kind), name)
255 }
256 ast::ModuleItem::UnionDef(it) => {
257 let id = self.source_ast_id_map.ast_id(&it);
258 let name = it.name();
259 (DefKind::Union(id), name)
260 }
261 ast::ModuleItem::EnumDef(it) => {
262 (DefKind::Enum(self.source_ast_id_map.ast_id(&it)), it.name())
263 }
264 ast::ModuleItem::FnDef(it) => {
265 (DefKind::Function(self.source_ast_id_map.ast_id(&it)), it.name())
266 }
267 ast::ModuleItem::TraitDef(it) => {
268 (DefKind::Trait(self.source_ast_id_map.ast_id(&it)), it.name())
269 }
270 ast::ModuleItem::TypeAliasDef(it) => {
271 (DefKind::TypeAlias(self.source_ast_id_map.ast_id(&it)), it.name())
272 }
273 ast::ModuleItem::ConstDef(it) => {
274 (DefKind::Const(self.source_ast_id_map.ast_id(&it)), it.name())
275 }
276 ast::ModuleItem::StaticDef(it) => {
277 (DefKind::Static(self.source_ast_id_map.ast_id(&it)), it.name())
278 }
279 ast::ModuleItem::MacroCall(it) => {
280 self.add_macro(current_module, it);
281 return;
282 }
283 ast::ModuleItem::ExternBlock(it) => {
284 self.add_extern_block(current_module, it);
285 return;
286 }
287 };
288 if let Some(name) = name {
289 let name = name.as_name();
290 let def = self.raw_items.defs.alloc(DefData { name, kind, visibility });
291 self.push_item(current_module, attrs, RawItemKind::Def(def));
292 }
293 }
294
295 fn add_extern_block(
296 &mut self,
297 current_module: Option<Idx<ModuleData>>,
298 block: ast::ExternBlock,
299 ) {
300 if let Some(items) = block.extern_item_list() {
301 for item in items.extern_items() {
302 let attrs = self.parse_attrs(&item);
303 let visibility =
304 RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene);
305 let (kind, name) = match item {
306 ast::ExternItem::FnDef(it) => {
307 (DefKind::Function(self.source_ast_id_map.ast_id(&it)), it.name())
308 }
309 ast::ExternItem::StaticDef(it) => {
310 (DefKind::Static(self.source_ast_id_map.ast_id(&it)), it.name())
311 }
312 };
313
314 if let Some(name) = name {
315 let name = name.as_name();
316 let def = self.raw_items.defs.alloc(DefData { name, kind, visibility });
317 self.push_item(current_module, attrs, RawItemKind::Def(def));
318 }
319 }
320 }
321 }
322
323 fn add_module(&mut self, current_module: Option<Idx<ModuleData>>, module: ast::Module) {
324 let name = match module.name() {
325 Some(it) => it.as_name(),
326 None => return,
327 };
328 let attrs = self.parse_attrs(&module);
329 let visibility = RawVisibility::from_ast_with_hygiene(module.visibility(), &self.hygiene);
330
331 let ast_id = self.source_ast_id_map.ast_id(&module);
332 if module.semicolon_token().is_some() {
333 let item =
334 self.raw_items.modules.alloc(ModuleData::Declaration { name, visibility, ast_id });
335 self.push_item(current_module, attrs, RawItemKind::Module(item));
336 return;
337 }
338
339 if let Some(item_list) = module.item_list() {
340 let item = self.raw_items.modules.alloc(ModuleData::Definition {
341 name,
342 visibility,
343 ast_id,
344 items: Vec::new(),
345 });
346 self.process_module(Some(item), item_list);
347 self.push_item(current_module, attrs, RawItemKind::Module(item));
348 return;
349 }
350 mark::hit!(name_res_works_for_broken_modules);
351 }
352
353 fn add_use_item(&mut self, current_module: Option<Idx<ModuleData>>, use_item: ast::UseItem) {
354 // FIXME: cfg_attr
355 let is_prelude = use_item.has_atom_attr("prelude_import");
356 let attrs = self.parse_attrs(&use_item);
357 let visibility = RawVisibility::from_ast_with_hygiene(use_item.visibility(), &self.hygiene);
358
359 let mut buf = Vec::new();
360 ModPath::expand_use_item(
361 InFile { value: use_item, file_id: self.file_id },
362 &self.hygiene,
363 |path, _use_tree, is_glob, alias| {
364 let import_data = ImportData {
365 path,
366 alias,
367 is_glob,
368 is_prelude,
369 is_extern_crate: false,
370 is_macro_use: false,
371 visibility: visibility.clone(),
372 };
373 buf.push(import_data);
374 },
375 );
376 for import_data in buf {
377 self.push_import(current_module, attrs.clone(), import_data);
378 }
379 }
380
381 fn add_extern_crate_item(
382 &mut self,
383 current_module: Option<Idx<ModuleData>>,
384 extern_crate: ast::ExternCrateItem,
385 ) {
386 if let Some(name_ref) = extern_crate.name_ref() {
387 let path = ModPath::from_name_ref(&name_ref);
388 let visibility =
389 RawVisibility::from_ast_with_hygiene(extern_crate.visibility(), &self.hygiene);
390 let alias = extern_crate.alias().map(|a| {
391 a.name().map(|it| it.as_name()).map_or(ImportAlias::Underscore, ImportAlias::Alias)
392 });
393 let attrs = self.parse_attrs(&extern_crate);
394 // FIXME: cfg_attr
395 let is_macro_use = extern_crate.has_atom_attr("macro_use");
396 let import_data = ImportData {
397 path,
398 alias,
399 is_glob: false,
400 is_prelude: false,
401 is_extern_crate: true,
402 is_macro_use,
403 visibility,
404 };
405 self.push_import(current_module, attrs, import_data);
406 }
407 }
408
409 fn add_macro(&mut self, current_module: Option<Idx<ModuleData>>, m: ast::MacroCall) {
410 let attrs = self.parse_attrs(&m);
411 let path = match m.path().and_then(|path| ModPath::from_src(path, &self.hygiene)) {
412 Some(it) => it,
413 _ => return,
414 };
415
416 let name = m.name().map(|it| it.as_name());
417 let ast_id = self.source_ast_id_map.ast_id(&m);
418
419 // FIXME: cfg_attr
420 let export_attr = attrs.by_key("macro_export");
421
422 let export = export_attr.exists();
423 let local_inner = if export {
424 export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
425 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
426 ident.text.contains("local_inner_macros")
427 }
428 _ => false,
429 })
430 } else {
431 false
432 };
433
434 let builtin = attrs.by_key("rustc_builtin_macro").exists();
435
436 let m = self.raw_items.macros.alloc(MacroData {
437 ast_id,
438 path,
439 name,
440 export,
441 local_inner,
442 builtin,
443 });
444 self.push_item(current_module, attrs, RawItemKind::Macro(m));
445 }
446
447 fn add_impl(&mut self, current_module: Option<Idx<ModuleData>>, imp: ast::ImplDef) {
448 let attrs = self.parse_attrs(&imp);
449 let ast_id = self.source_ast_id_map.ast_id(&imp);
450 let imp = self.raw_items.impls.alloc(ImplData { ast_id });
451 self.push_item(current_module, attrs, RawItemKind::Impl(imp))
452 }
453
454 fn push_import(
455 &mut self,
456 current_module: Option<Idx<ModuleData>>,
457 attrs: Attrs,
458 data: ImportData,
459 ) {
460 let import = self.raw_items.imports.alloc(data);
461 self.push_item(current_module, attrs, RawItemKind::Import(import))
462 }
463
464 fn push_item(
465 &mut self,
466 current_module: Option<Idx<ModuleData>>,
467 attrs: Attrs,
468 kind: RawItemKind,
469 ) {
470 match current_module {
471 Some(module) => match &mut self.raw_items.modules[module] {
472 ModuleData::Definition { items, .. } => items,
473 ModuleData::Declaration { .. } => unreachable!(),
474 },
475 None => &mut self.raw_items.items,
476 }
477 .push(RawItem { attrs, kind })
478 }
479
480 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
481 Attrs::new(item, &self.hygiene)
482 }
483}