diff options
-rw-r--r-- | crates/ra_hir/src/ids.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 160 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 5 |
4 files changed, 99 insertions, 107 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index c5408e277..b93b7f397 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use ra_db::{SourceRootId, LocationIntener, FileId}; | 1 | use ra_db::{SourceRootId, LocationIntener, FileId}; |
2 | use ra_syntax::{TreeArc, SyntaxKind, SyntaxNode, SourceFile, AstNode, ast}; | 2 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; |
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 3 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | HirDatabase, PerNs, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, | 6 | HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, |
7 | Module, Trait, Type, Static, Const, | 7 | Module, Trait, Type, Static, Const, |
8 | module_tree::ModuleId, | 8 | module_tree::ModuleId, |
9 | }; | 9 | }; |
@@ -238,23 +238,6 @@ impl DefLoc { | |||
238 | } | 238 | } |
239 | } | 239 | } |
240 | 240 | ||
241 | impl DefKind { | ||
242 | pub(crate) fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { | ||
243 | match kind { | ||
244 | SyntaxKind::FN_DEF => PerNs::values(DefKind::Function), | ||
245 | SyntaxKind::MODULE => PerNs::types(DefKind::Module), | ||
246 | SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), | ||
247 | SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), | ||
248 | // These define items, but don't have their own DefKinds yet: | ||
249 | SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), | ||
250 | SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type), | ||
251 | SyntaxKind::CONST_DEF => PerNs::values(DefKind::Const), | ||
252 | SyntaxKind::STATIC_DEF => PerNs::values(DefKind::Static), | ||
253 | _ => PerNs::none(), | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /// Identifier of item within a specific file. This is stable over reparses, so | 241 | /// Identifier of item within a specific file. This is stable over reparses, so |
259 | /// it's OK to use it as a salsa key/value. | 242 | /// it's OK to use it as a salsa key/value. |
260 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 243 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 72791ed49..1d163edf7 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -21,7 +21,6 @@ use crate::nameres::lower::*; | |||
21 | use std::sync::Arc; | 21 | use std::sync::Arc; |
22 | 22 | ||
23 | use rustc_hash::{FxHashMap, FxHashSet}; | 23 | use rustc_hash::{FxHashMap, FxHashSet}; |
24 | use ra_syntax::SyntaxKind::*; | ||
25 | use ra_db::SourceRootId; | 24 | use ra_db::SourceRootId; |
26 | 25 | ||
27 | use crate::{ | 26 | use crate::{ |
@@ -235,27 +234,12 @@ where | |||
235 | } | 234 | } |
236 | } | 235 | } |
237 | // Populate explicitly declared items, except modules | 236 | // Populate explicitly declared items, except modules |
238 | for item in input.items.iter() { | 237 | for (name, &def_id) in input.declarations.iter() { |
239 | if item.kind == MODULE { | ||
240 | continue; | ||
241 | } | ||
242 | // depending on the item kind, the location can define something in | ||
243 | // the values namespace, the types namespace, or both | ||
244 | let kind = DefKind::for_syntax_kind(item.kind); | ||
245 | let def_id = kind.map(|k| { | ||
246 | let def_loc = DefLoc { | ||
247 | kind: k, | ||
248 | source_root_id: self.source_root, | ||
249 | module_id, | ||
250 | source_item_id: item.id, | ||
251 | }; | ||
252 | def_loc.id(self.db) | ||
253 | }); | ||
254 | let resolution = Resolution { | 238 | let resolution = Resolution { |
255 | def_id, | 239 | def_id, |
256 | import: None, | 240 | import: None, |
257 | }; | 241 | }; |
258 | module_items.items.insert(item.name.clone(), resolution); | 242 | module_items.items.insert(name.clone(), resolution); |
259 | } | 243 | } |
260 | 244 | ||
261 | // Populate modules | 245 | // Populate modules |
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 921ba3c98..270f9ab03 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -2,52 +2,18 @@ use std::sync::Arc; | |||
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, | 4 | SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, |
5 | ast::{self, ModuleItemOwner}, | 5 | ast::{self, ModuleItemOwner, NameOwner}, |
6 | }; | 6 | }; |
7 | use ra_db::SourceRootId; | 7 | use ra_db::SourceRootId; |
8 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 8 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
9 | use rustc_hash::FxHashMap; | ||
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, | 12 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, |
12 | HirFileId, MacroCallLoc, AsName, | 13 | HirFileId, MacroCallLoc, AsName, PerNs, DefId, DefKind, DefLoc, |
13 | module_tree::ModuleId | 14 | module_tree::ModuleId |
14 | }; | 15 | }; |
15 | 16 | ||
16 | #[derive(Debug, PartialEq, Eq)] | ||
17 | pub(super) enum Vis { | ||
18 | // Priv, | ||
19 | Other, | ||
20 | } | ||
21 | |||
22 | #[derive(Debug, PartialEq, Eq)] | ||
23 | pub(crate) struct ModuleItem { | ||
24 | pub(crate) id: SourceItemId, | ||
25 | pub(crate) name: Name, | ||
26 | pub(super) kind: SyntaxKind, | ||
27 | pub(super) vis: Vis, | ||
28 | } | ||
29 | |||
30 | impl ModuleItem { | ||
31 | fn new( | ||
32 | file_id: HirFileId, | ||
33 | file_items: &SourceFileItems, | ||
34 | item: &impl ast::NameOwner, | ||
35 | ) -> Option<ModuleItem> { | ||
36 | let name = item.name()?.as_name(); | ||
37 | let kind = item.syntax().kind(); | ||
38 | let vis = Vis::Other; | ||
39 | let item_id = Some(file_items.id_of_unchecked(item.syntax())); | ||
40 | let id = SourceItemId { file_id, item_id }; | ||
41 | let res = ModuleItem { | ||
42 | id, | ||
43 | name, | ||
44 | kind, | ||
45 | vis, | ||
46 | }; | ||
47 | Some(res) | ||
48 | } | ||
49 | } | ||
50 | |||
51 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 17 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
52 | pub struct ImportId(RawId); | 18 | pub struct ImportId(RawId); |
53 | impl_arena_id!(ImportId); | 19 | impl_arena_id!(ImportId); |
@@ -66,7 +32,7 @@ pub(super) struct ImportData { | |||
66 | /// can avoid redoing name resolution. | 32 | /// can avoid redoing name resolution. |
67 | #[derive(Debug, Default, PartialEq, Eq)] | 33 | #[derive(Debug, Default, PartialEq, Eq)] |
68 | pub struct LoweredModule { | 34 | pub struct LoweredModule { |
69 | pub(crate) items: Vec<ModuleItem>, | 35 | pub(crate) declarations: FxHashMap<Name, PerNs<DefId>>, |
70 | pub(super) imports: Arena<ImportId, ImportData>, | 36 | pub(super) imports: Arena<ImportId, ImportData>, |
71 | } | 37 | } |
72 | 38 | ||
@@ -157,7 +123,15 @@ impl LoweredModule { | |||
157 | for item in items { | 123 | for item in items { |
158 | match item { | 124 | match item { |
159 | ast::ItemOrMacro::Item(it) => { | 125 | ast::ItemOrMacro::Item(it) => { |
160 | self.add_item(source_map, file_id, &file_items, it); | 126 | self.add_def_id( |
127 | source_map, | ||
128 | db, | ||
129 | source_root_id, | ||
130 | module_id, | ||
131 | file_id, | ||
132 | &file_items, | ||
133 | it, | ||
134 | ); | ||
161 | } | 135 | } |
162 | ast::ItemOrMacro::Macro(macro_call) => { | 136 | ast::ItemOrMacro::Macro(macro_call) => { |
163 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); | 137 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); |
@@ -174,54 +148,60 @@ impl LoweredModule { | |||
174 | let file_items = db.file_items(file_id); | 148 | let file_items = db.file_items(file_id); |
175 | //FIXME: expand recursively | 149 | //FIXME: expand recursively |
176 | for item in db.hir_source_file(file_id).items() { | 150 | for item in db.hir_source_file(file_id).items() { |
177 | self.add_item(source_map, file_id, &file_items, item); | 151 | self.add_def_id( |
152 | source_map, | ||
153 | db, | ||
154 | source_root_id, | ||
155 | module_id, | ||
156 | file_id, | ||
157 | &file_items, | ||
158 | item, | ||
159 | ); | ||
178 | } | 160 | } |
179 | } | 161 | } |
180 | } | 162 | } |
181 | } | 163 | } |
182 | } | 164 | } |
183 | 165 | ||
184 | fn add_item( | 166 | fn add_def_id( |
185 | &mut self, | 167 | &mut self, |
186 | source_map: &mut ImportSourceMap, | 168 | source_map: &mut ImportSourceMap, |
169 | db: &impl HirDatabase, | ||
170 | source_root_id: SourceRootId, | ||
171 | module_id: ModuleId, | ||
187 | file_id: HirFileId, | 172 | file_id: HirFileId, |
188 | file_items: &SourceFileItems, | 173 | file_items: &SourceFileItems, |
189 | item: &ast::ModuleItem, | 174 | item: &ast::ModuleItem, |
190 | ) -> Option<()> { | 175 | ) { |
191 | match item.kind() { | 176 | let name = match item.kind() { |
192 | ast::ModuleItemKind::StructDef(it) => { | 177 | ast::ModuleItemKind::StructDef(it) => it.name(), |
193 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 178 | ast::ModuleItemKind::EnumDef(it) => it.name(), |
194 | } | 179 | ast::ModuleItemKind::FnDef(it) => it.name(), |
195 | ast::ModuleItemKind::EnumDef(it) => { | 180 | ast::ModuleItemKind::TraitDef(it) => it.name(), |
196 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 181 | ast::ModuleItemKind::TypeDef(it) => it.name(), |
197 | } | ||
198 | ast::ModuleItemKind::FnDef(it) => { | ||
199 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
200 | } | ||
201 | ast::ModuleItemKind::TraitDef(it) => { | ||
202 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
203 | } | ||
204 | ast::ModuleItemKind::TypeDef(it) => { | ||
205 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
206 | } | ||
207 | ast::ModuleItemKind::ImplBlock(_) => { | 182 | ast::ModuleItemKind::ImplBlock(_) => { |
208 | // impls don't define items | 183 | // impls don't define items |
184 | return; | ||
185 | } | ||
186 | ast::ModuleItemKind::UseItem(it) => { | ||
187 | self.add_use_item(source_map, it); | ||
188 | return; | ||
209 | } | 189 | } |
210 | ast::ModuleItemKind::UseItem(it) => self.add_use_item(source_map, it), | ||
211 | ast::ModuleItemKind::ExternCrateItem(_) => { | 190 | ast::ModuleItemKind::ExternCrateItem(_) => { |
212 | // TODO | 191 | // TODO |
192 | return; | ||
213 | } | 193 | } |
214 | ast::ModuleItemKind::ConstDef(it) => { | 194 | ast::ModuleItemKind::ConstDef(it) => it.name(), |
215 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 195 | ast::ModuleItemKind::StaticDef(it) => it.name(), |
216 | } | 196 | ast::ModuleItemKind::Module(_) => { |
217 | ast::ModuleItemKind::StaticDef(it) => { | 197 | // modules are handled separately direclty by nameres |
218 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | 198 | return; |
219 | } | ||
220 | ast::ModuleItemKind::Module(it) => { | ||
221 | self.items.push(ModuleItem::new(file_id, file_items, it)?) | ||
222 | } | 199 | } |
200 | }; | ||
201 | if let Some(name) = name { | ||
202 | let def_id = assign_def_id(db, source_root_id, module_id, file_id, file_items, item); | ||
203 | self.declarations.insert(name.as_name(), def_id); | ||
223 | } | 204 | } |
224 | Some(()) | ||
225 | } | 205 | } |
226 | 206 | ||
227 | fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { | 207 | fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) { |
@@ -236,3 +216,47 @@ impl LoweredModule { | |||
236 | }) | 216 | }) |
237 | } | 217 | } |
238 | } | 218 | } |
219 | |||
220 | fn assign_def_id( | ||
221 | db: &impl HirDatabase, | ||
222 | source_root_id: SourceRootId, | ||
223 | module_id: ModuleId, | ||
224 | file_id: HirFileId, | ||
225 | file_items: &SourceFileItems, | ||
226 | item: &ast::ModuleItem, | ||
227 | ) -> PerNs<DefId> { | ||
228 | // depending on the item kind, the location can define something in | ||
229 | // the values namespace, the types namespace, or both | ||
230 | let kind = DefKind::for_syntax_kind(item.syntax().kind()); | ||
231 | let def_id = kind.map(|k| { | ||
232 | let item_id = file_items.id_of_unchecked(item.syntax()); | ||
233 | let def_loc = DefLoc { | ||
234 | kind: k, | ||
235 | source_root_id, | ||
236 | module_id, | ||
237 | source_item_id: SourceItemId { | ||
238 | file_id, | ||
239 | item_id: Some(item_id), | ||
240 | }, | ||
241 | }; | ||
242 | def_loc.id(db) | ||
243 | }); | ||
244 | def_id | ||
245 | } | ||
246 | |||
247 | impl DefKind { | ||
248 | fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { | ||
249 | match kind { | ||
250 | SyntaxKind::FN_DEF => PerNs::values(DefKind::Function), | ||
251 | SyntaxKind::MODULE => PerNs::types(DefKind::Module), | ||
252 | SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), | ||
253 | SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), | ||
254 | // These define items, but don't have their own DefKinds yet: | ||
255 | SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), | ||
256 | SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type), | ||
257 | SyntaxKind::CONST_DEF => PerNs::values(DefKind::Const), | ||
258 | SyntaxKind::STATIC_DEF => PerNs::values(DefKind::Static), | ||
259 | _ => PerNs::none(), | ||
260 | } | ||
261 | } | ||
262 | } | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 2fe354b04..bde0be37b 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -146,9 +146,10 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te | |||
146 | let mut res = Vec::new(); | 146 | let mut res = Vec::new(); |
147 | 147 | ||
148 | for macro_call_id in items | 148 | for macro_call_id in items |
149 | .items | 149 | .declarations |
150 | .iter() | 150 | .iter() |
151 | .filter_map(|it| it.id.file_id.as_macro_call_id()) | 151 | .filter_map(|(_, it)| it.take_types()) |
152 | .filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id()) | ||
152 | { | 153 | { |
153 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { | 154 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { |
154 | let loc = macro_call_id.loc(db); | 155 | let loc = macro_call_id.loc(db); |