diff options
author | Seivan Heidari <[email protected]> | 2019-11-25 00:54:54 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-11-25 00:54:54 +0000 |
commit | 15ea338ac991707d330288ba4d1bf5daa0fc75d9 (patch) | |
tree | 16aeab28bcdb07d36aae28e3fb4a385614865a48 /crates/ra_hir_def/src/nameres/raw.rs | |
parent | eb7363d167c7a9f7c73cb950b621eb1dce493318 (diff) | |
parent | f7f9757b6b144385ab8ce57b15764473b1f57331 (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir_def/src/nameres/raw.rs')
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 76 |
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 | ||
3 | use std::{ops::Index, sync::Arc}; | 8 | use std::{ops::Index, sync::Arc}; |
4 | 9 | ||
@@ -12,11 +17,14 @@ use hir_expand::{ | |||
12 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 17 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
13 | use ra_syntax::{ | 18 | use ra_syntax::{ |
14 | ast::{self, AttrsOwner, NameOwner}, | 19 | ast::{self, AttrsOwner, NameOwner}, |
15 | AstNode, AstPtr, SourceFile, | 20 | AstNode, AstPtr, |
16 | }; | 21 | }; |
17 | use test_utils::tested_by; | 22 | use test_utils::tested_by; |
18 | 23 | ||
19 | use crate::{attr::Attr, db::DefDatabase2, path::Path, FileAstId, HirFileId, ModuleSource, Source}; | 24 | use 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)] |
26 | pub struct RawItems { | 34 | pub 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)] |
37 | pub struct ImportSourceMap { | 45 | pub struct ImportSourceMap { |
38 | map: ArenaMap<ImportId, ImportSourcePtr>, | 46 | map: ArenaMap<LocalImportId, ImportSourcePtr>, |
39 | } | 47 | } |
40 | 48 | ||
41 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; | 49 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; |
42 | type ImportSource = Either<ast::UseTree, ast::ExternCrateItem>; | ||
43 | |||
44 | fn 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 | ||
48 | impl ImportSourceMap { | 51 | impl 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 | ||
63 | impl RawItems { | 57 | impl 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 | ||
104 | impl Index<ImportId> for RawItems { | 102 | impl 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. | ||
133 | type Attrs = Option<Arc<[Attr]>>; | ||
134 | |||
135 | #[derive(Debug, PartialEq, Eq, Clone)] | 130 | #[derive(Debug, PartialEq, Eq, Clone)] |
136 | pub(super) struct RawItem { | 131 | pub(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 | ||
141 | impl 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)] |
148 | pub(super) enum RawItemKind { | 137 | pub(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)] | ||
167 | pub struct ImportId(RawId); | ||
168 | impl_arena_id!(ImportId); | ||
169 | |||
170 | #[derive(Debug, Clone, PartialEq, Eq)] | 155 | #[derive(Debug, Clone, PartialEq, Eq)] |
171 | pub struct ImportData { | 156 | pub struct ImportData { |
172 | pub(super) path: Path, | 157 | pub(super) path: Path, |
@@ -223,8 +208,8 @@ pub(super) struct ImplData { | |||
223 | 208 | ||
224 | struct RawItemsCollector { | 209 | struct 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 | } |