aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres/lower.rs')
-rw-r--r--crates/ra_hir/src/nameres/lower.rs85
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 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{ 3use 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};
7use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 7use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9 9
10use crate::{ 10use 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
230fn 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
255impl 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}