diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir_def/src/imp.rs | 71 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 29 |
6 files changed, 156 insertions, 21 deletions
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 40b5920d9..348aca07f 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -8,30 +8,32 @@ use ra_syntax::ast; | |||
8 | use crate::{ | 8 | use crate::{ |
9 | adt::{EnumData, StructData}, | 9 | adt::{EnumData, StructData}, |
10 | body::{scope::ExprScopes, Body, BodySourceMap}, | 10 | body::{scope::ExprScopes, Body, BodySourceMap}, |
11 | imp::ImplData, | ||
11 | nameres::{ | 12 | nameres::{ |
12 | raw::{ImportSourceMap, RawItems}, | 13 | raw::{ImportSourceMap, RawItems}, |
13 | CrateDefMap, | 14 | CrateDefMap, |
14 | }, | 15 | }, |
15 | DefWithBodyId, EnumId, StructOrUnionId, | 16 | DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, |
16 | }; | 17 | }; |
17 | 18 | ||
18 | #[salsa::query_group(InternDatabaseStorage)] | 19 | #[salsa::query_group(InternDatabaseStorage)] |
19 | pub trait InternDatabase: SourceDatabase { | 20 | pub trait InternDatabase: SourceDatabase { |
20 | #[salsa::interned] | 21 | #[salsa::interned] |
21 | fn intern_function(&self, loc: crate::ItemLoc<ast::FnDef>) -> crate::FunctionId; | 22 | fn intern_function(&self, loc: ItemLoc<ast::FnDef>) -> crate::FunctionId; |
22 | #[salsa::interned] | 23 | #[salsa::interned] |
23 | fn intern_struct_or_union(&self, loc: crate::ItemLoc<ast::StructDef>) | 24 | fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; |
24 | -> crate::StructOrUnionId; | ||
25 | #[salsa::interned] | 25 | #[salsa::interned] |
26 | fn intern_enum(&self, loc: crate::ItemLoc<ast::EnumDef>) -> crate::EnumId; | 26 | fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; |
27 | #[salsa::interned] | 27 | #[salsa::interned] |
28 | fn intern_const(&self, loc: crate::ItemLoc<ast::ConstDef>) -> crate::ConstId; | 28 | fn intern_const(&self, loc: ItemLoc<ast::ConstDef>) -> crate::ConstId; |
29 | #[salsa::interned] | 29 | #[salsa::interned] |
30 | fn intern_static(&self, loc: crate::ItemLoc<ast::StaticDef>) -> crate::StaticId; | 30 | fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; |
31 | #[salsa::interned] | 31 | #[salsa::interned] |
32 | fn intern_trait(&self, loc: crate::ItemLoc<ast::TraitDef>) -> crate::TraitId; | 32 | fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; |
33 | #[salsa::interned] | 33 | #[salsa::interned] |
34 | fn intern_type_alias(&self, loc: crate::ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId; | 34 | fn intern_type_alias(&self, loc: ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId; |
35 | #[salsa::interned] | ||
36 | fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; | ||
35 | } | 37 | } |
36 | 38 | ||
37 | #[salsa::query_group(DefDatabase2Storage)] | 39 | #[salsa::query_group(DefDatabase2Storage)] |
@@ -54,6 +56,9 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { | |||
54 | #[salsa::invoke(EnumData::enum_data_query)] | 56 | #[salsa::invoke(EnumData::enum_data_query)] |
55 | fn enum_data(&self, e: EnumId) -> Arc<EnumData>; | 57 | fn enum_data(&self, e: EnumId) -> Arc<EnumData>; |
56 | 58 | ||
59 | #[salsa::invoke(ImplData::impl_data_query)] | ||
60 | fn impl_data(&self, e: ImplId) -> Arc<ImplData>; | ||
61 | |||
57 | #[salsa::invoke(Body::body_with_source_map_query)] | 62 | #[salsa::invoke(Body::body_with_source_map_query)] |
58 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); | 63 | fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); |
59 | 64 | ||
diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/imp.rs new file mode 100644 index 000000000..717991c40 --- /dev/null +++ b/crates/ra_hir_def/src/imp.rs | |||
@@ -0,0 +1,71 @@ | |||
1 | //! Defines hir-level representation of impls. | ||
2 | //! | ||
3 | //! The handling is similar, but is not quite the same as for other items, | ||
4 | //! because `impl`s don't have names. | ||
5 | |||
6 | use std::sync::Arc; | ||
7 | |||
8 | use ra_syntax::ast; | ||
9 | |||
10 | use crate::{ | ||
11 | db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId, | ||
12 | LocationCtx, TypeAliasId, | ||
13 | }; | ||
14 | |||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
16 | pub struct ImplData { | ||
17 | target_trait: Option<TypeRef>, | ||
18 | target_type: TypeRef, | ||
19 | items: Vec<AssocItemId>, | ||
20 | negative: bool, | ||
21 | } | ||
22 | |||
23 | impl ImplData { | ||
24 | pub(crate) fn impl_data_query(db: &impl DefDatabase2, id: ImplId) -> Arc<ImplData> { | ||
25 | let src = id.source(db); | ||
26 | let items = db.ast_id_map(src.file_id); | ||
27 | |||
28 | let target_trait = src.ast.target_trait().map(TypeRef::from_ast); | ||
29 | let target_type = TypeRef::from_ast_opt(src.ast.target_type()); | ||
30 | let negative = src.ast.is_negative(); | ||
31 | |||
32 | let items = if let Some(item_list) = src.ast.item_list() { | ||
33 | let ctx = LocationCtx::new(db, id.module(db), src.file_id); | ||
34 | item_list | ||
35 | .impl_items() | ||
36 | .map(|item_node| match item_node { | ||
37 | ast::ImplItem::FnDef(it) => { | ||
38 | FunctionId::from_ast_id(ctx, items.ast_id(&it)).into() | ||
39 | } | ||
40 | ast::ImplItem::ConstDef(it) => { | ||
41 | ConstId::from_ast_id(ctx, items.ast_id(&it)).into() | ||
42 | } | ||
43 | ast::ImplItem::TypeAliasDef(it) => { | ||
44 | TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() | ||
45 | } | ||
46 | }) | ||
47 | .collect() | ||
48 | } else { | ||
49 | Vec::new() | ||
50 | }; | ||
51 | |||
52 | let res = ImplData { target_trait, target_type, items, negative }; | ||
53 | Arc::new(res) | ||
54 | } | ||
55 | |||
56 | pub fn target_trait(&self) -> Option<&TypeRef> { | ||
57 | self.target_trait.as_ref() | ||
58 | } | ||
59 | |||
60 | pub fn target_type(&self) -> &TypeRef { | ||
61 | &self.target_type | ||
62 | } | ||
63 | |||
64 | pub fn items(&self) -> &[AssocItemId] { | ||
65 | &self.items | ||
66 | } | ||
67 | |||
68 | pub fn is_negative(&self) -> bool { | ||
69 | self.negative | ||
70 | } | ||
71 | } | ||
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 3fab7965c..a240a10b8 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -13,6 +13,7 @@ pub mod path; | |||
13 | pub mod type_ref; | 13 | pub mod type_ref; |
14 | pub mod builtin_type; | 14 | pub mod builtin_type; |
15 | pub mod adt; | 15 | pub mod adt; |
16 | pub mod imp; | ||
16 | pub mod diagnostics; | 17 | pub mod diagnostics; |
17 | pub mod expr; | 18 | pub mod expr; |
18 | pub mod body; | 19 | pub mod body; |
@@ -77,14 +78,13 @@ impl ModuleSource { | |||
77 | } | 78 | } |
78 | } | 79 | } |
79 | 80 | ||
80 | pub fn from_child_node( | 81 | pub fn from_child_node(db: &impl db::DefDatabase2, child: Source<&SyntaxNode>) -> ModuleSource { |
81 | db: &impl db::DefDatabase2, | 82 | if let Some(m) = |
82 | file_id: FileId, | 83 | child.ast.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) |
83 | child: &SyntaxNode, | 84 | { |
84 | ) -> ModuleSource { | ||
85 | if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { | ||
86 | ModuleSource::Module(m) | 85 | ModuleSource::Module(m) |
87 | } else { | 86 | } else { |
87 | let file_id = child.file_id.original_file(db); | ||
88 | let source_file = db.parse(file_id).tree(); | 88 | let source_file = db.parse(file_id).tree(); |
89 | ModuleSource::SourceFile(source_file) | 89 | ModuleSource::SourceFile(source_file) |
90 | } | 90 | } |
@@ -321,6 +321,18 @@ impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { | |||
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
324 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
325 | pub struct ImplId(salsa::InternId); | ||
326 | impl_intern_key!(ImplId); | ||
327 | impl AstItemDef<ast::ImplBlock> for ImplId { | ||
328 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ImplBlock>) -> Self { | ||
329 | db.intern_impl(loc) | ||
330 | } | ||
331 | fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ImplBlock> { | ||
332 | db.lookup_intern_impl(self) | ||
333 | } | ||
334 | } | ||
335 | |||
324 | macro_rules! impl_froms { | 336 | macro_rules! impl_froms { |
325 | ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { | 337 | ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { |
326 | $( | 338 | $( |
@@ -384,3 +396,15 @@ pub enum DefWithBodyId { | |||
384 | } | 396 | } |
385 | 397 | ||
386 | impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); | 398 | impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); |
399 | |||
400 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | ||
401 | pub enum AssocItemId { | ||
402 | FunctionId(FunctionId), | ||
403 | ConstId(ConstId), | ||
404 | TypeAliasId(TypeAliasId), | ||
405 | } | ||
406 | // FIXME: not every function, ... is actually an assoc item. maybe we should make | ||
407 | // sure that you can only turn actual assoc items into AssocItemIds. This would | ||
408 | // require not implementing From, and instead having some checked way of | ||
409 | // casting them, and somehow making the constructors private, which would be annoying. | ||
410 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); | ||
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index dfcec6443..e5b073a0f 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -73,7 +73,7 @@ use crate::{ | |||
73 | diagnostics::DefDiagnostic, path_resolution::ResolveMode, per_ns::PerNs, raw::ImportId, | 73 | diagnostics::DefDiagnostic, path_resolution::ResolveMode, per_ns::PerNs, raw::ImportId, |
74 | }, | 74 | }, |
75 | path::Path, | 75 | path::Path, |
76 | AstId, CrateModuleId, FunctionId, ModuleDefId, ModuleId, TraitId, | 76 | AstId, CrateModuleId, FunctionId, ImplId, ModuleDefId, ModuleId, TraitId, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /// Contains all top-level defs from a macro-expanded crate | 79 | /// Contains all top-level defs from a macro-expanded crate |
@@ -122,14 +122,15 @@ pub struct ModuleData { | |||
122 | /// | 122 | /// |
123 | /// Note that non-inline modules, by definition, live inside non-macro file. | 123 | /// Note that non-inline modules, by definition, live inside non-macro file. |
124 | pub definition: Option<FileId>, | 124 | pub definition: Option<FileId>, |
125 | pub impls: Vec<ImplId>, | ||
125 | } | 126 | } |
126 | 127 | ||
127 | #[derive(Default, Debug, PartialEq, Eq, Clone)] | 128 | #[derive(Default, Debug, PartialEq, Eq)] |
128 | pub(crate) struct Declarations { | 129 | pub(crate) struct Declarations { |
129 | fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>, | 130 | fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>, |
130 | } | 131 | } |
131 | 132 | ||
132 | #[derive(Debug, Default, PartialEq, Eq, Clone)] | 133 | #[derive(Debug, Default, PartialEq, Eq)] |
133 | pub struct ModuleScope { | 134 | pub struct ModuleScope { |
134 | items: FxHashMap<Name, Resolution>, | 135 | items: FxHashMap<Name, Resolution>, |
135 | /// Macros visable in current module in legacy textual scope | 136 | /// Macros visable in current module in legacy textual scope |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 5c899aff3..c9ccb9023 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, | 19 | per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, |
20 | }, | 20 | }, |
21 | path::{Path, PathKind}, | 21 | path::{Path, PathKind}, |
22 | AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, | 22 | AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, ImplId, |
23 | LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId, | 23 | LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId, |
24 | UnionId, | 24 | UnionId, |
25 | }; | 25 | }; |
@@ -571,6 +571,15 @@ where | |||
571 | .push((self.module_id, import_id, self.raw_items[import_id].clone())), | 571 | .push((self.module_id, import_id, self.raw_items[import_id].clone())), |
572 | raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]), | 572 | raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]), |
573 | raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]), | 573 | raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]), |
574 | raw::RawItemKind::Impl(imp) => { | ||
575 | let module = ModuleId { | ||
576 | krate: self.def_collector.def_map.krate, | ||
577 | module_id: self.module_id, | ||
578 | }; | ||
579 | let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); | ||
580 | let imp_id = ImplId::from_ast_id(ctx, self.raw_items[imp].ast_id); | ||
581 | self.def_collector.def_map.modules[self.module_id].impls.push(imp_id) | ||
582 | } | ||
574 | } | 583 | } |
575 | } | 584 | } |
576 | } | 585 | } |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index f52002bc0..a0a2c7273 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -28,6 +28,7 @@ pub struct RawItems { | |||
28 | imports: Arena<ImportId, ImportData>, | 28 | imports: Arena<ImportId, ImportData>, |
29 | defs: Arena<Def, DefData>, | 29 | defs: Arena<Def, DefData>, |
30 | macros: Arena<Macro, MacroData>, | 30 | macros: Arena<Macro, MacroData>, |
31 | impls: Arena<Impl, ImplData>, | ||
31 | /// items for top-level module | 32 | /// items for top-level module |
32 | items: Vec<RawItem>, | 33 | items: Vec<RawItem>, |
33 | } | 34 | } |
@@ -121,6 +122,13 @@ impl Index<Macro> for RawItems { | |||
121 | } | 122 | } |
122 | } | 123 | } |
123 | 124 | ||
125 | impl Index<Impl> for RawItems { | ||
126 | type Output = ImplData; | ||
127 | fn index(&self, idx: Impl) -> &ImplData { | ||
128 | &self.impls[idx] | ||
129 | } | ||
130 | } | ||
131 | |||
124 | // Avoid heap allocation on items without attributes. | 132 | // Avoid heap allocation on items without attributes. |
125 | type Attrs = Option<Arc<[Attr]>>; | 133 | type Attrs = Option<Arc<[Attr]>>; |
126 | 134 | ||
@@ -142,6 +150,7 @@ pub(super) enum RawItemKind { | |||
142 | Import(ImportId), | 150 | Import(ImportId), |
143 | Def(Def), | 151 | Def(Def), |
144 | Macro(Macro), | 152 | Macro(Macro), |
153 | Impl(Impl), | ||
145 | } | 154 | } |
146 | 155 | ||
147 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 156 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -203,6 +212,15 @@ pub(super) struct MacroData { | |||
203 | pub(super) builtin: bool, | 212 | pub(super) builtin: bool, |
204 | } | 213 | } |
205 | 214 | ||
215 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
216 | pub(super) struct Impl(RawId); | ||
217 | impl_arena_id!(Impl); | ||
218 | |||
219 | #[derive(Debug, PartialEq, Eq)] | ||
220 | pub(super) struct ImplData { | ||
221 | pub(super) ast_id: FileAstId<ast::ImplBlock>, | ||
222 | } | ||
223 | |||
206 | struct RawItemsCollector { | 224 | struct RawItemsCollector { |
207 | raw_items: RawItems, | 225 | raw_items: RawItems, |
208 | source_ast_id_map: Arc<AstIdMap>, | 226 | source_ast_id_map: Arc<AstIdMap>, |
@@ -236,8 +254,8 @@ impl RawItemsCollector { | |||
236 | self.add_extern_crate_item(current_module, extern_crate); | 254 | self.add_extern_crate_item(current_module, extern_crate); |
237 | return; | 255 | return; |
238 | } | 256 | } |
239 | ast::ModuleItem::ImplBlock(_) => { | 257 | ast::ModuleItem::ImplBlock(it) => { |
240 | // impls don't participate in name resolution | 258 | self.add_impl(current_module, it); |
241 | return; | 259 | return; |
242 | } | 260 | } |
243 | ast::ModuleItem::StructDef(it) => { | 261 | ast::ModuleItem::StructDef(it) => { |
@@ -376,6 +394,13 @@ impl RawItemsCollector { | |||
376 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); | 394 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); |
377 | } | 395 | } |
378 | 396 | ||
397 | fn add_impl(&mut self, current_module: Option<Module>, imp: ast::ImplBlock) { | ||
398 | let attrs = self.parse_attrs(&imp); | ||
399 | let ast_id = self.source_ast_id_map.ast_id(&imp); | ||
400 | let imp = self.raw_items.impls.alloc(ImplData { ast_id }); | ||
401 | self.push_item(current_module, attrs, RawItemKind::Impl(imp)) | ||
402 | } | ||
403 | |||
379 | fn push_import( | 404 | fn push_import( |
380 | &mut self, | 405 | &mut self, |
381 | current_module: Option<Module>, | 406 | current_module: Option<Module>, |