aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/ids.rs21
-rw-r--r--crates/ra_hir/src/nameres.rs20
-rw-r--r--crates/ra_hir/src/nameres/lower.rs160
-rw-r--r--crates/ra_hir/src/source_binder.rs5
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 @@
1use ra_db::{SourceRootId, LocationIntener, FileId}; 1use ra_db::{SourceRootId, LocationIntener, FileId};
2use ra_syntax::{TreeArc, SyntaxKind, SyntaxNode, SourceFile, AstNode, ast}; 2use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast};
3use ra_arena::{Arena, RawId, impl_arena_id}; 3use ra_arena::{Arena, RawId, impl_arena_id};
4 4
5use crate::{ 5use 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
241impl 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::*;
21use std::sync::Arc; 21use std::sync::Arc;
22 22
23use rustc_hash::{FxHashMap, FxHashSet}; 23use rustc_hash::{FxHashMap, FxHashSet};
24use ra_syntax::SyntaxKind::*;
25use ra_db::SourceRootId; 24use ra_db::SourceRootId;
26 25
27use crate::{ 26use 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
3use ra_syntax::{ 3use 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};
7use ra_db::SourceRootId; 7use ra_db::SourceRootId;
8use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 8use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
9use rustc_hash::FxHashMap;
9 10
10use crate::{ 11use 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)]
17pub(super) enum Vis {
18 // Priv,
19 Other,
20}
21
22#[derive(Debug, PartialEq, Eq)]
23pub(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
30impl 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)]
52pub struct ImportId(RawId); 18pub struct ImportId(RawId);
53impl_arena_id!(ImportId); 19impl_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)]
68pub struct LoweredModule { 34pub 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
220fn 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
247impl 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);