diff options
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 85 |
1 files changed, 21 insertions, 64 deletions
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 6a86e5fd4..b4fe99ea7 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -1,16 +1,16 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, | 4 | AstNode, SourceFile, TreeArc, AstPtr, |
5 | ast::{self, ModuleItemOwner, NameOwner}, | 5 | ast::{self, ModuleItemOwner, NameOwner}, |
6 | }; | 6 | }; |
7 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 7 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, | 11 | SourceItemId, Path, ModuleSource, HirDatabase, Name, |
12 | HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function, | 12 | HirFileId, MacroCallLoc, AsName, PerNs, Function, |
13 | ModuleDef, Module, Struct, Enum, Const, Static, | 13 | ModuleDef, Module, Struct, Enum, Const, Static, Trait, Type, |
14 | ids::LocationCtx, | 14 | ids::LocationCtx, |
15 | }; | 15 | }; |
16 | 16 | ||
@@ -115,7 +115,7 @@ impl LoweredModule { | |||
115 | for item in items { | 115 | for item in items { |
116 | match item { | 116 | match item { |
117 | ast::ItemOrMacro::Item(it) => { | 117 | ast::ItemOrMacro::Item(it) => { |
118 | self.add_def_id(source_map, db, module, file_id, &file_items, it); | 118 | self.add_def_id(source_map, db, module, file_id, it); |
119 | } | 119 | } |
120 | ast::ItemOrMacro::Macro(macro_call) => { | 120 | ast::ItemOrMacro::Macro(macro_call) => { |
121 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); | 121 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); |
@@ -128,10 +128,9 @@ impl LoweredModule { | |||
128 | }; | 128 | }; |
129 | let id = loc.id(db); | 129 | let id = loc.id(db); |
130 | let file_id = HirFileId::from(id); | 130 | let file_id = HirFileId::from(id); |
131 | let file_items = db.file_items(file_id); | ||
132 | //FIXME: expand recursively | 131 | //FIXME: expand recursively |
133 | for item in db.hir_source_file(file_id).items() { | 132 | for item in db.hir_source_file(file_id).items() { |
134 | self.add_def_id(source_map, db, module, file_id, &file_items, item); | 133 | self.add_def_id(source_map, db, module, file_id, item); |
135 | } | 134 | } |
136 | } | 135 | } |
137 | } | 136 | } |
@@ -144,18 +143,16 @@ impl LoweredModule { | |||
144 | db: &impl HirDatabase, | 143 | db: &impl HirDatabase, |
145 | module: Module, | 144 | module: Module, |
146 | file_id: HirFileId, | 145 | file_id: HirFileId, |
147 | file_items: &SourceFileItems, | ||
148 | item: &ast::ModuleItem, | 146 | item: &ast::ModuleItem, |
149 | ) { | 147 | ) { |
150 | let ctx = LocationCtx::new(db, module, file_id); | 148 | let ctx = LocationCtx::new(db, module, file_id); |
151 | let name = match item.kind() { | 149 | match item.kind() { |
152 | ast::ModuleItemKind::StructDef(it) => { | 150 | ast::ModuleItemKind::StructDef(it) => { |
153 | if let Some(name) = it.name() { | 151 | if let Some(name) = it.name() { |
154 | let s = Struct { id: ctx.to_def(it) }; | 152 | let s = Struct { id: ctx.to_def(it) }; |
155 | let s: ModuleDef = s.into(); | 153 | let s: ModuleDef = s.into(); |
156 | self.declarations.insert(name.as_name(), PerNs::both(s, s)); | 154 | self.declarations.insert(name.as_name(), PerNs::both(s, s)); |
157 | } | 155 | } |
158 | return; | ||
159 | } | 156 | } |
160 | ast::ModuleItemKind::EnumDef(it) => { | 157 | ast::ModuleItemKind::EnumDef(it) => { |
161 | if let Some(name) = it.name() { | 158 | if let Some(name) = it.name() { |
@@ -163,7 +160,6 @@ impl LoweredModule { | |||
163 | let e: ModuleDef = e.into(); | 160 | let e: ModuleDef = e.into(); |
164 | self.declarations.insert(name.as_name(), PerNs::types(e)); | 161 | self.declarations.insert(name.as_name(), PerNs::types(e)); |
165 | } | 162 | } |
166 | return; | ||
167 | } | 163 | } |
168 | ast::ModuleItemKind::FnDef(it) => { | 164 | ast::ModuleItemKind::FnDef(it) => { |
169 | if let Some(name) = it.name() { | 165 | if let Some(name) = it.name() { |
@@ -171,21 +167,29 @@ impl LoweredModule { | |||
171 | self.declarations | 167 | self.declarations |
172 | .insert(name.as_name(), PerNs::values(func.into())); | 168 | .insert(name.as_name(), PerNs::values(func.into())); |
173 | } | 169 | } |
174 | return; | ||
175 | } | 170 | } |
176 | ast::ModuleItemKind::TraitDef(it) => it.name(), | 171 | ast::ModuleItemKind::TraitDef(it) => { |
177 | ast::ModuleItemKind::TypeDef(it) => it.name(), | 172 | if let Some(name) = it.name() { |
173 | let t = Trait { id: ctx.to_def(it) }; | ||
174 | self.declarations | ||
175 | .insert(name.as_name(), PerNs::types(t.into())); | ||
176 | } | ||
177 | } | ||
178 | ast::ModuleItemKind::TypeDef(it) => { | ||
179 | if let Some(name) = it.name() { | ||
180 | let t = Type { id: ctx.to_def(it) }; | ||
181 | self.declarations | ||
182 | .insert(name.as_name(), PerNs::types(t.into())); | ||
183 | } | ||
184 | } | ||
178 | ast::ModuleItemKind::ImplBlock(_) => { | 185 | ast::ModuleItemKind::ImplBlock(_) => { |
179 | // impls don't define items | 186 | // impls don't define items |
180 | return; | ||
181 | } | 187 | } |
182 | ast::ModuleItemKind::UseItem(it) => { | 188 | ast::ModuleItemKind::UseItem(it) => { |
183 | self.add_use_item(source_map, it); | 189 | self.add_use_item(source_map, it); |
184 | return; | ||
185 | } | 190 | } |
186 | ast::ModuleItemKind::ExternCrateItem(_) => { | 191 | ast::ModuleItemKind::ExternCrateItem(_) => { |
187 | // TODO | 192 | // TODO |
188 | return; | ||
189 | } | 193 | } |
190 | ast::ModuleItemKind::ConstDef(it) => { | 194 | ast::ModuleItemKind::ConstDef(it) => { |
191 | if let Some(name) = it.name() { | 195 | if let Some(name) = it.name() { |
@@ -193,7 +197,6 @@ impl LoweredModule { | |||
193 | self.declarations | 197 | self.declarations |
194 | .insert(name.as_name(), PerNs::values(c.into())); | 198 | .insert(name.as_name(), PerNs::values(c.into())); |
195 | } | 199 | } |
196 | return; | ||
197 | } | 200 | } |
198 | ast::ModuleItemKind::StaticDef(it) => { | 201 | ast::ModuleItemKind::StaticDef(it) => { |
199 | if let Some(name) = it.name() { | 202 | if let Some(name) = it.name() { |
@@ -201,17 +204,11 @@ impl LoweredModule { | |||
201 | self.declarations | 204 | self.declarations |
202 | .insert(name.as_name(), PerNs::values(s.into())); | 205 | .insert(name.as_name(), PerNs::values(s.into())); |
203 | } | 206 | } |
204 | return; | ||
205 | } | 207 | } |
206 | ast::ModuleItemKind::Module(_) => { | 208 | ast::ModuleItemKind::Module(_) => { |
207 | // modules are handled separately direclty by nameres | 209 | // modules are handled separately direclty by nameres |
208 | return; | ||
209 | } | 210 | } |
210 | }; | 211 | }; |
211 | if let Some(name) = name { | ||
212 | let def_id = assign_def_id(db, module, file_id, file_items, item); | ||
213 | self.declarations.insert(name.as_name(), def_id); | ||
214 | } | ||
215 | } | 212 | } |
216 | 213 | ||
217 | fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { | 214 | fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { |
@@ -226,43 +223,3 @@ impl LoweredModule { | |||
226 | }) | 223 | }) |
227 | } | 224 | } |
228 | } | 225 | } |
229 | |||
230 | fn assign_def_id( | ||
231 | db: &impl HirDatabase, | ||
232 | module: Module, | ||
233 | file_id: HirFileId, | ||
234 | file_items: &SourceFileItems, | ||
235 | item: &ast::ModuleItem, | ||
236 | ) -> PerNs<ModuleDef> { | ||
237 | // depending on the item kind, the location can define something in | ||
238 | // the values namespace, the types namespace, or both | ||
239 | let kind = DefKind::for_syntax_kind(item.syntax().kind()); | ||
240 | let def_id = kind.map(|k| { | ||
241 | let item_id = file_items.id_of_unchecked(item.syntax()); | ||
242 | let def_loc = DefLoc { | ||
243 | kind: k, | ||
244 | module, | ||
245 | source_item_id: SourceItemId { | ||
246 | file_id, | ||
247 | item_id: Some(item_id), | ||
248 | }, | ||
249 | }; | ||
250 | def_loc.id(db).into() | ||
251 | }); | ||
252 | def_id | ||
253 | } | ||
254 | |||
255 | impl DefKind { | ||
256 | fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { | ||
257 | match kind { | ||
258 | SyntaxKind::FN_DEF => unreachable!(), | ||
259 | SyntaxKind::STRUCT_DEF => unreachable!(), | ||
260 | SyntaxKind::ENUM_DEF => unreachable!(), | ||
261 | SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), | ||
262 | SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type), | ||
263 | SyntaxKind::CONST_DEF => unreachable!(), | ||
264 | SyntaxKind::STATIC_DEF => unreachable!(), | ||
265 | _ => PerNs::none(), | ||
266 | } | ||
267 | } | ||
268 | } | ||