aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres/raw.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres/raw.rs')
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs76
1 files changed, 30 insertions, 46 deletions
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 7c68fd638..401af031c 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -1,4 +1,9 @@
1//! FIXME: write short doc here 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.
2 7
3use std::{ops::Index, sync::Arc}; 8use std::{ops::Index, sync::Arc};
4 9
@@ -12,11 +17,14 @@ use hir_expand::{
12use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 17use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
13use ra_syntax::{ 18use ra_syntax::{
14 ast::{self, AttrsOwner, NameOwner}, 19 ast::{self, AttrsOwner, NameOwner},
15 AstNode, AstPtr, SourceFile, 20 AstNode, AstPtr,
16}; 21};
17use test_utils::tested_by; 22use test_utils::tested_by;
18 23
19use crate::{attr::Attr, db::DefDatabase2, path::Path, FileAstId, HirFileId, ModuleSource, Source}; 24use crate::{
25 attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, LocalImportId,
26 Source,
27};
20 28
21/// `RawItems` is a set of top-level items in a file (except for impls). 29/// `RawItems` is a set of top-level items in a file (except for impls).
22/// 30///
@@ -25,7 +33,7 @@ use crate::{attr::Attr, db::DefDatabase2, path::Path, FileAstId, HirFileId, Modu
25#[derive(Debug, Default, PartialEq, Eq)] 33#[derive(Debug, Default, PartialEq, Eq)]
26pub struct RawItems { 34pub struct RawItems {
27 modules: Arena<Module, ModuleData>, 35 modules: Arena<Module, ModuleData>,
28 imports: Arena<ImportId, ImportData>, 36 imports: Arena<LocalImportId, ImportData>,
29 defs: Arena<Def, DefData>, 37 defs: Arena<Def, DefData>,
30 macros: Arena<Macro, MacroData>, 38 macros: Arena<Macro, MacroData>,
31 impls: Arena<Impl, ImplData>, 39 impls: Arena<Impl, ImplData>,
@@ -35,47 +43,33 @@ pub struct RawItems {
35 43
36#[derive(Debug, Default, PartialEq, Eq)] 44#[derive(Debug, Default, PartialEq, Eq)]
37pub struct ImportSourceMap { 45pub struct ImportSourceMap {
38 map: ArenaMap<ImportId, ImportSourcePtr>, 46 map: ArenaMap<LocalImportId, ImportSourcePtr>,
39} 47}
40 48
41type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; 49type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
42type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>;
43
44fn to_node(ptr: ImportSourcePtr, file: &SourceFile) -> ImportSource {
45 ptr.map(|ptr| ptr.to_node(file.syntax()), |ptr| ptr.to_node(file.syntax()))
46}
47 50
48impl ImportSourceMap { 51impl ImportSourceMap {
49 fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { 52 pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
50 self.map.insert(import, ptr) 53 self.map[import].clone()
51 }
52
53 pub fn get(&self, source: &ModuleSource, import: ImportId) -> ImportSource {
54 let file = match source {
55 ModuleSource::SourceFile(file) => file.clone(),
56 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
57 };
58
59 to_node(self.map[import], &file)
60 } 54 }
61} 55}
62 56
63impl RawItems { 57impl RawItems {
64 pub(crate) fn raw_items_query( 58 pub(crate) fn raw_items_query(
65 db: &(impl DefDatabase2 + AstDatabase), 59 db: &(impl DefDatabase + AstDatabase),
66 file_id: HirFileId, 60 file_id: HirFileId,
67 ) -> Arc<RawItems> { 61 ) -> Arc<RawItems> {
68 db.raw_items_with_source_map(file_id).0 62 db.raw_items_with_source_map(file_id).0
69 } 63 }
70 64
71 pub(crate) fn raw_items_with_source_map_query( 65 pub(crate) fn raw_items_with_source_map_query(
72 db: &(impl DefDatabase2 + AstDatabase), 66 db: &(impl DefDatabase + AstDatabase),
73 file_id: HirFileId, 67 file_id: HirFileId,
74 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { 68 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
75 let mut collector = RawItemsCollector { 69 let mut collector = RawItemsCollector {
76 raw_items: RawItems::default(), 70 raw_items: RawItems::default(),
77 source_ast_id_map: db.ast_id_map(file_id), 71 source_ast_id_map: db.ast_id_map(file_id),
78 source_map: ImportSourceMap::default(), 72 imports: Trace::new(),
79 file_id, 73 file_id,
80 hygiene: Hygiene::new(db, file_id), 74 hygiene: Hygiene::new(db, file_id),
81 }; 75 };
@@ -86,7 +80,11 @@ impl RawItems {
86 collector.process_module(None, item_list); 80 collector.process_module(None, item_list);
87 } 81 }
88 } 82 }
89 (Arc::new(collector.raw_items), Arc::new(collector.source_map)) 83 let mut raw_items = collector.raw_items;
84 let (arena, map) = collector.imports.into_arena_and_map();
85 raw_items.imports = arena;
86 let source_map = ImportSourceMap { map };
87 (Arc::new(raw_items), Arc::new(source_map))
90 } 88 }
91 89
92 pub(super) fn items(&self) -> &[RawItem] { 90 pub(super) fn items(&self) -> &[RawItem] {
@@ -101,9 +99,9 @@ impl Index<Module> for RawItems {
101 } 99 }
102} 100}
103 101
104impl Index<ImportId> for RawItems { 102impl Index<LocalImportId> for RawItems {
105 type Output = ImportData; 103 type Output = ImportData;
106 fn index(&self, idx: ImportId) -> &ImportData { 104 fn index(&self, idx: LocalImportId) -> &ImportData {
107 &self.imports[idx] 105 &self.imports[idx]
108 } 106 }
109} 107}
@@ -129,25 +127,16 @@ impl Index<Impl> for RawItems {
129 } 127 }
130} 128}
131 129
132// Avoid heap allocation on items without attributes.
133type Attrs = Option<Arc<[Attr]>>;
134
135#[derive(Debug, PartialEq, Eq, Clone)] 130#[derive(Debug, PartialEq, Eq, Clone)]
136pub(super) struct RawItem { 131pub(super) struct RawItem {
137 attrs: Attrs, 132 pub(super) attrs: Attrs,
138 pub(super) kind: RawItemKind, 133 pub(super) kind: RawItemKind,
139} 134}
140 135
141impl RawItem {
142 pub(super) fn attrs(&self) -> &[Attr] {
143 self.attrs.as_ref().map_or(&[], |it| &*it)
144 }
145}
146
147#[derive(Debug, PartialEq, Eq, Clone, Copy)] 136#[derive(Debug, PartialEq, Eq, Clone, Copy)]
148pub(super) enum RawItemKind { 137pub(super) enum RawItemKind {
149 Module(Module), 138 Module(Module),
150 Import(ImportId), 139 Import(LocalImportId),
151 Def(Def), 140 Def(Def),
152 Macro(Macro), 141 Macro(Macro),
153 Impl(Impl), 142 Impl(Impl),
@@ -163,10 +152,6 @@ pub(super) enum ModuleData {
163 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, 152 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
164} 153}
165 154
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
167pub struct ImportId(RawId);
168impl_arena_id!(ImportId);
169
170#[derive(Debug, Clone, PartialEq, Eq)] 155#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct ImportData { 156pub struct ImportData {
172 pub(super) path: Path, 157 pub(super) path: Path,
@@ -223,8 +208,8 @@ pub(super) struct ImplData {
223 208
224struct RawItemsCollector { 209struct RawItemsCollector {
225 raw_items: RawItems, 210 raw_items: RawItems,
211 imports: Trace<LocalImportId, ImportData, ImportSourcePtr>,
226 source_ast_id_map: Arc<AstIdMap>, 212 source_ast_id_map: Arc<AstIdMap>,
227 source_map: ImportSourceMap,
228 file_id: HirFileId, 213 file_id: HirFileId,
229 hygiene: Hygiene, 214 hygiene: Hygiene,
230} 215}
@@ -408,8 +393,7 @@ impl RawItemsCollector {
408 data: ImportData, 393 data: ImportData,
409 source: ImportSourcePtr, 394 source: ImportSourcePtr,
410 ) { 395 ) {
411 let import = self.raw_items.imports.alloc(data); 396 let import = self.imports.alloc(|| source, || data);
412 self.source_map.insert(import, source);
413 self.push_item(current_module, attrs, RawItemKind::Import(import)) 397 self.push_item(current_module, attrs, RawItemKind::Import(import))
414 } 398 }
415 399
@@ -425,6 +409,6 @@ impl RawItemsCollector {
425 } 409 }
426 410
427 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { 411 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
428 Attr::from_attrs_owner(item, &self.hygiene) 412 Attrs::new(item, &self.hygiene)
429 } 413 }
430} 414}