aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-03-14 10:14:54 +0000
committerAleksey Kladov <[email protected]>2019-03-17 09:52:52 +0000
commitb2a6c1736295a5fffa5ac0d0fee835cdc719ada3 (patch)
tree56fd27197126f11011fe9030cd9bfb80e142e709 /crates/ra_hir/src/nameres
parentc7259a899c1709753dcda0fb117e2f7cc30a4d6e (diff)
remove lower module
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/collector.rs9
-rw-r--r--crates/ra_hir/src/nameres/crate_def_map/raw.rs16
-rw-r--r--crates/ra_hir/src/nameres/lower.rs190
3 files changed, 27 insertions, 188 deletions
diff --git a/crates/ra_hir/src/nameres/crate_def_map/collector.rs b/crates/ra_hir/src/nameres/crate_def_map/collector.rs
index 8b727e2c9..0f500ce42 100644
--- a/crates/ra_hir/src/nameres/crate_def_map/collector.rs
+++ b/crates/ra_hir/src/nameres/crate_def_map/collector.rs
@@ -224,7 +224,7 @@ where
224 } 224 }
225 } 225 }
226 let resolution = Resolution { def, import: Some(import_id) }; 226 let resolution = Resolution { def, import: Some(import_id) };
227 self.update(module_id, None, &[(name, resolution)]); 227 self.update(module_id, Some(import_id), &[(name, resolution)]);
228 } 228 }
229 } 229 }
230 230
@@ -262,6 +262,13 @@ where
262 existing.import = import.or(res.import); 262 existing.import = import.or(res.import);
263 changed = true; 263 changed = true;
264 } 264 }
265 if existing.def.is_none()
266 && res.def.is_none()
267 && existing.import.is_none()
268 && res.import.is_some()
269 {
270 existing.import = res.import;
271 }
265 } 272 }
266 if !changed { 273 if !changed {
267 return; 274 return;
diff --git a/crates/ra_hir/src/nameres/crate_def_map/raw.rs b/crates/ra_hir/src/nameres/crate_def_map/raw.rs
index f064f722c..dca86e394 100644
--- a/crates/ra_hir/src/nameres/crate_def_map/raw.rs
+++ b/crates/ra_hir/src/nameres/crate_def_map/raw.rs
@@ -14,6 +14,7 @@ use ra_syntax::{
14use crate::{ 14use crate::{
15 PersistentHirDatabase, Name, AsName, Path, HirFileId, 15 PersistentHirDatabase, Name, AsName, Path, HirFileId,
16 ids::{SourceFileItemId, SourceFileItems}, 16 ids::{SourceFileItemId, SourceFileItems},
17 nameres::lower::ImportSourceMap,
17}; 18};
18 19
19#[derive(Debug, Default, PartialEq, Eq)] 20#[derive(Debug, Default, PartialEq, Eq)]
@@ -31,13 +32,21 @@ impl RawItems {
31 db: &impl PersistentHirDatabase, 32 db: &impl PersistentHirDatabase,
32 file_id: FileId, 33 file_id: FileId,
33 ) -> Arc<RawItems> { 34 ) -> Arc<RawItems> {
35 db.raw_items_with_source_map(file_id).0
36 }
37
38 pub(crate) fn raw_items_with_source_map_query(
39 db: &impl PersistentHirDatabase,
40 file_id: FileId,
41 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
34 let mut collector = RawItemsCollector { 42 let mut collector = RawItemsCollector {
35 raw_items: RawItems::default(), 43 raw_items: RawItems::default(),
36 source_file_items: db.file_items(file_id.into()), 44 source_file_items: db.file_items(file_id.into()),
45 source_map: ImportSourceMap::default(),
37 }; 46 };
38 let source_file = db.parse(file_id); 47 let source_file = db.parse(file_id);
39 collector.process_module(None, &*source_file); 48 collector.process_module(None, &*source_file);
40 Arc::new(collector.raw_items) 49 (Arc::new(collector.raw_items), Arc::new(collector.source_map))
41 } 50 }
42 51
43 pub(crate) fn items(&self) -> &[RawItem] { 52 pub(crate) fn items(&self) -> &[RawItem] {
@@ -51,6 +60,7 @@ impl RawItems {
51 let mut collector = RawItemsCollector { 60 let mut collector = RawItemsCollector {
52 raw_items: RawItems::default(), 61 raw_items: RawItems::default(),
53 source_file_items: Arc::new(source_file_items), 62 source_file_items: Arc::new(source_file_items),
63 source_map: ImportSourceMap::default(),
54 }; 64 };
55 collector.process_module(None, &*source_file); 65 collector.process_module(None, &*source_file);
56 collector.raw_items 66 collector.raw_items
@@ -144,6 +154,7 @@ pub(crate) struct MacroData {
144struct RawItemsCollector { 154struct RawItemsCollector {
145 raw_items: RawItems, 155 raw_items: RawItems,
146 source_file_items: Arc<SourceFileItems>, 156 source_file_items: Arc<SourceFileItems>,
157 source_map: ImportSourceMap,
147} 158}
148 159
149impl RawItemsCollector { 160impl RawItemsCollector {
@@ -227,6 +238,9 @@ impl RawItemsCollector {
227 is_prelude, 238 is_prelude,
228 is_extern_crate: false, 239 is_extern_crate: false,
229 }); 240 });
241 if let Some(segment) = segment {
242 self.source_map.insert(import, segment)
243 }
230 self.push_item(current_module, RawItem::Import(import)) 244 self.push_item(current_module, RawItem::Import(import))
231 }) 245 })
232 } 246 }
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs
index 24707aed1..d4c7f2481 100644
--- a/crates/ra_hir/src/nameres/lower.rs
+++ b/crates/ra_hir/src/nameres/lower.rs
@@ -1,18 +1,10 @@
1use std::sync::Arc;
2
3use ra_syntax::{ 1use ra_syntax::{
4 AstNode, SourceFile, TreeArc, AstPtr, 2 AstNode, SourceFile, TreeArc, AstPtr,
5 ast::{self, ModuleItemOwner, NameOwner, AttrsOwner}, 3 ast,
6}; 4};
7use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 5use ra_arena::{RawId, impl_arena_id, map::ArenaMap};
8use rustc_hash::FxHashMap;
9 6
10use crate::{ 7use crate::{Path, ModuleSource, Name};
11 SourceItemId, Path, ModuleSource, Name,
12 HirFileId, MacroCallLoc, AsName, PerNs, Function,
13 ModuleDef, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
14 ids::LocationCtx, PersistentHirDatabase,
15};
16 8
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub struct ImportId(RawId); 10pub struct ImportId(RawId);
@@ -27,25 +19,13 @@ pub struct ImportData {
27 pub(super) is_extern_crate: bool, 19 pub(super) is_extern_crate: bool,
28} 20}
29 21
30/// A set of items and imports declared inside a module, without relation to
31/// other modules.
32///
33/// This sits in-between raw syntax and name resolution and allows us to avoid
34/// recomputing name res: if two instance of `InputModuleItems` are the same, we
35/// can avoid redoing name resolution.
36#[derive(Debug, Default, PartialEq, Eq)]
37pub struct LoweredModule {
38 pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>,
39 pub(super) imports: Arena<ImportId, ImportData>,
40}
41
42#[derive(Debug, Default, PartialEq, Eq)] 22#[derive(Debug, Default, PartialEq, Eq)]
43pub struct ImportSourceMap { 23pub struct ImportSourceMap {
44 map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>, 24 map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>,
45} 25}
46 26
47impl ImportSourceMap { 27impl ImportSourceMap {
48 fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { 28 pub(crate) fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
49 self.map.insert(import, AstPtr::new(segment)) 29 self.map.insert(import, AstPtr::new(segment))
50 } 30 }
51 31
@@ -58,165 +38,3 @@ impl ImportSourceMap {
58 self.map[import].to_node(file).to_owned() 38 self.map[import].to_node(file).to_owned()
59 } 39 }
60} 40}
61
62impl LoweredModule {
63 pub(crate) fn lower_module_query(
64 db: &impl PersistentHirDatabase,
65 module: Module,
66 ) -> Arc<LoweredModule> {
67 db.lower_module_with_source_map(module).0
68 }
69
70 pub(crate) fn lower_module_with_source_map_query(
71 db: &impl PersistentHirDatabase,
72 module: Module,
73 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
74 let (file_id, source) = module.definition_source(db);
75 let file_id: HirFileId = file_id.into();
76 let mut source_map = ImportSourceMap::default();
77 let mut res = LoweredModule::default();
78 match source {
79 ModuleSource::SourceFile(it) => {
80 res.fill(&mut source_map, db, module, file_id, &mut it.items_with_macros())
81 }
82 ModuleSource::Module(it) => {
83 if let Some(item_list) = it.item_list() {
84 res.fill(
85 &mut source_map,
86 db,
87 module,
88 file_id,
89 &mut item_list.items_with_macros(),
90 )
91 }
92 }
93 };
94 (Arc::new(res), Arc::new(source_map))
95 }
96
97 fn fill(
98 &mut self,
99 source_map: &mut ImportSourceMap,
100 db: &impl PersistentHirDatabase,
101 module: Module,
102 file_id: HirFileId,
103 items: &mut Iterator<Item = ast::ItemOrMacro>,
104 ) {
105 let file_items = db.file_items(file_id);
106
107 for item in items {
108 match item {
109 ast::ItemOrMacro::Item(it) => {
110 self.add_def_id(source_map, db, module, file_id, it);
111 }
112 ast::ItemOrMacro::Macro(macro_call) => {
113 let item_id = file_items.id_of_unchecked(macro_call.syntax());
114 let loc =
115 MacroCallLoc { module, source_item_id: SourceItemId { file_id, item_id } };
116 let id = loc.id(db);
117 let file_id = HirFileId::from(id);
118 //FIXME: expand recursively
119 for item in db.hir_parse(file_id).items() {
120 self.add_def_id(source_map, db, module, file_id, item);
121 }
122 }
123 }
124 }
125 }
126
127 fn add_def_id(
128 &mut self,
129 source_map: &mut ImportSourceMap,
130 db: &impl PersistentHirDatabase,
131 module: Module,
132 file_id: HirFileId,
133 item: &ast::ModuleItem,
134 ) {
135 let ctx = LocationCtx::new(db, module, file_id);
136 match item.kind() {
137 ast::ModuleItemKind::StructDef(it) => {
138 if let Some(name) = it.name() {
139 let s = Struct { id: ctx.to_def(it) };
140 let s: ModuleDef = s.into();
141 self.declarations.insert(name.as_name(), PerNs::both(s, s));
142 }
143 }
144 ast::ModuleItemKind::EnumDef(it) => {
145 if let Some(name) = it.name() {
146 let e = Enum { id: ctx.to_def(it) };
147 let e: ModuleDef = e.into();
148 self.declarations.insert(name.as_name(), PerNs::types(e));
149 }
150 }
151 ast::ModuleItemKind::FnDef(it) => {
152 if let Some(name) = it.name() {
153 let func = Function { id: ctx.to_def(it) };
154 self.declarations.insert(name.as_name(), PerNs::values(func.into()));
155 }
156 }
157 ast::ModuleItemKind::TraitDef(it) => {
158 if let Some(name) = it.name() {
159 let t = Trait { id: ctx.to_def(it) };
160 self.declarations.insert(name.as_name(), PerNs::types(t.into()));
161 }
162 }
163 ast::ModuleItemKind::TypeAliasDef(it) => {
164 if let Some(name) = it.name() {
165 let t = TypeAlias { id: ctx.to_def(it) };
166 self.declarations.insert(name.as_name(), PerNs::types(t.into()));
167 }
168 }
169 ast::ModuleItemKind::ImplBlock(_) => {
170 // impls don't define items
171 }
172 ast::ModuleItemKind::UseItem(it) => {
173 self.add_use_item(source_map, it);
174 }
175 ast::ModuleItemKind::ExternCrateItem(it) => {
176 if let Some(name_ref) = it.name_ref() {
177 let path = Path::from_name_ref(name_ref);
178 let alias = it.alias().and_then(|a| a.name()).map(AsName::as_name);
179 self.imports.alloc(ImportData {
180 path,
181 alias,
182 is_glob: false,
183 is_prelude: false,
184 is_extern_crate: true,
185 });
186 }
187 }
188 ast::ModuleItemKind::ConstDef(it) => {
189 if let Some(name) = it.name() {
190 let c = Const { id: ctx.to_def(it) };
191 self.declarations.insert(name.as_name(), PerNs::values(c.into()));
192 }
193 }
194 ast::ModuleItemKind::StaticDef(it) => {
195 if let Some(name) = it.name() {
196 let s = Static { id: ctx.to_def(it) };
197 self.declarations.insert(name.as_name(), PerNs::values(s.into()));
198 }
199 }
200 ast::ModuleItemKind::Module(_) => {
201 // modules are handled separately directly by name res
202 }
203 };
204 }
205
206 fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
207 let is_prelude =
208 item.attrs().any(|attr| attr.as_atom().map(|s| s == "prelude_import").unwrap_or(false));
209 Path::expand_use_item(item, |path, segment, alias| {
210 let import = self.imports.alloc(ImportData {
211 path,
212 alias,
213 is_glob: segment.is_none(),
214 is_prelude,
215 is_extern_crate: false,
216 });
217 if let Some(segment) = segment {
218 source_map.insert(import, segment)
219 }
220 })
221 }
222}