diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/function.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 78 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 6 |
6 files changed, 72 insertions, 92 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index b2631d6a6..ad3f9c405 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -8,42 +8,18 @@ use ra_syntax::{ | |||
8 | }; | 8 | }; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | Name, AsName, Struct, Enum, EnumVariant, Module, HirFileId, | 11 | Name, AsName, Struct, Enum, EnumVariant, |
12 | HirDatabase, | 12 | HirDatabase, |
13 | type_ref::TypeRef, | 13 | type_ref::TypeRef, |
14 | ids::ItemLoc, | 14 | ids::LocationCtx, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | impl Struct { | 17 | impl Struct { |
18 | pub(crate) fn from_ast( | ||
19 | db: &impl HirDatabase, | ||
20 | module: Module, | ||
21 | file_id: HirFileId, | ||
22 | ast: &ast::StructDef, | ||
23 | ) -> Struct { | ||
24 | let loc = ItemLoc::from_ast(db, module, file_id, ast); | ||
25 | let id = db.as_ref().structs.loc2id(&loc); | ||
26 | Struct { id } | ||
27 | } | ||
28 | |||
29 | pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { | 18 | pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { |
30 | db.struct_data((*self).into()).variant_data.clone() | 19 | db.struct_data((*self).into()).variant_data.clone() |
31 | } | 20 | } |
32 | } | 21 | } |
33 | 22 | ||
34 | impl Enum { | ||
35 | pub(crate) fn from_ast( | ||
36 | db: &impl HirDatabase, | ||
37 | module: Module, | ||
38 | file_id: HirFileId, | ||
39 | ast: &ast::EnumDef, | ||
40 | ) -> Enum { | ||
41 | let loc = ItemLoc::from_ast(db, module, file_id, ast); | ||
42 | let id = db.as_ref().enums.loc2id(&loc); | ||
43 | Enum { id } | ||
44 | } | ||
45 | } | ||
46 | |||
47 | #[derive(Debug, Clone, PartialEq, Eq)] | 23 | #[derive(Debug, Clone, PartialEq, Eq)] |
48 | pub struct StructData { | 24 | pub struct StructData { |
49 | pub(crate) name: Option<Name>, | 25 | pub(crate) name: Option<Name>, |
@@ -64,19 +40,6 @@ impl StructData { | |||
64 | } | 40 | } |
65 | } | 41 | } |
66 | 42 | ||
67 | impl EnumVariant { | ||
68 | pub(crate) fn from_ast( | ||
69 | db: &impl HirDatabase, | ||
70 | module: Module, | ||
71 | file_id: HirFileId, | ||
72 | ast: &ast::EnumVariant, | ||
73 | ) -> EnumVariant { | ||
74 | let loc = ItemLoc::from_ast(db, module, file_id, ast); | ||
75 | let id = db.as_ref().enum_variants.loc2id(&loc); | ||
76 | EnumVariant { id } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | #[derive(Debug, Clone, PartialEq, Eq)] | 43 | #[derive(Debug, Clone, PartialEq, Eq)] |
81 | pub struct EnumData { | 44 | pub struct EnumData { |
82 | pub(crate) name: Option<Name>, | 45 | pub(crate) name: Option<Name>, |
@@ -92,11 +55,15 @@ impl EnumData { | |||
92 | pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> { | 55 | pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> { |
93 | let (file_id, enum_def) = e.source(db); | 56 | let (file_id, enum_def) = e.source(db); |
94 | let module = e.module(db); | 57 | let module = e.module(db); |
58 | let ctx = LocationCtx::new(db, module, file_id); | ||
95 | let variants = if let Some(vl) = enum_def.variant_list() { | 59 | let variants = if let Some(vl) = enum_def.variant_list() { |
96 | vl.variants() | 60 | vl.variants() |
97 | .filter_map(|variant_def| { | 61 | .filter_map(|variant_def| { |
98 | let name = variant_def.name().map(|n| n.as_name()); | 62 | let name = variant_def.name()?.as_name(); |
99 | name.map(|n| (n, EnumVariant::from_ast(db, module, file_id, variant_def))) | 63 | let var = EnumVariant { |
64 | id: ctx.to_def(variant_def), | ||
65 | }; | ||
66 | Some((name, var)) | ||
100 | }) | 67 | }) |
101 | .collect() | 68 | .collect() |
102 | } else { | 69 | } else { |
@@ -131,7 +98,10 @@ impl EnumVariantData { | |||
131 | ) -> Arc<EnumVariantData> { | 98 | ) -> Arc<EnumVariantData> { |
132 | let (file_id, variant_def) = var.source(db); | 99 | let (file_id, variant_def) = var.source(db); |
133 | let enum_def = variant_def.parent_enum(); | 100 | let enum_def = variant_def.parent_enum(); |
134 | let e = Enum::from_ast(db, var.module(db), file_id, enum_def); | 101 | let ctx = LocationCtx::new(db, var.module(db), file_id); |
102 | let e = Enum { | ||
103 | id: ctx.to_def(enum_def), | ||
104 | }; | ||
135 | Arc::new(EnumVariantData::new(&*variant_def, e)) | 105 | Arc::new(EnumVariantData::new(&*variant_def, e)) |
136 | } | 106 | } |
137 | } | 107 | } |
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index 6ce5c77b1..e0dd4d629 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -5,27 +5,15 @@ use std::sync::Arc; | |||
5 | use ra_syntax::ast::{self, NameOwner}; | 5 | use ra_syntax::ast::{self, NameOwner}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | HirDatabase, Name, AsName, Function, FnSignature, Module, HirFileId, | 8 | HirDatabase, Name, AsName, Function, FnSignature, |
9 | type_ref::{TypeRef, Mutability}, | 9 | type_ref::{TypeRef, Mutability}, |
10 | expr::Body, | 10 | expr::Body, |
11 | impl_block::ImplBlock, | 11 | impl_block::ImplBlock, |
12 | ids::ItemLoc, | ||
13 | }; | 12 | }; |
14 | 13 | ||
15 | pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; | 14 | pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; |
16 | 15 | ||
17 | impl Function { | 16 | impl Function { |
18 | pub(crate) fn from_ast( | ||
19 | db: &impl HirDatabase, | ||
20 | module: Module, | ||
21 | file_id: HirFileId, | ||
22 | ast: &ast::FnDef, | ||
23 | ) -> Function { | ||
24 | let loc = ItemLoc::from_ast(db, module, file_id, ast); | ||
25 | let id = db.as_ref().fns.loc2id(&loc); | ||
26 | Function { id } | ||
27 | } | ||
28 | |||
29 | pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> { | 17 | pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> { |
30 | db.body_hir(*self) | 18 | db.body_hir(*self) |
31 | } | 19 | } |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 262047849..4b4e07e58 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -16,10 +16,10 @@ use crate::{ | |||
16 | pub struct HirInterner { | 16 | pub struct HirInterner { |
17 | defs: LocationIntener<DefLoc, DefId>, | 17 | defs: LocationIntener<DefLoc, DefId>, |
18 | macros: LocationIntener<MacroCallLoc, MacroCallId>, | 18 | macros: LocationIntener<MacroCallLoc, MacroCallId>, |
19 | pub(crate) fns: LocationIntener<ItemLoc<ast::FnDef>, FunctionId>, | 19 | fns: LocationIntener<ItemLoc<ast::FnDef>, FunctionId>, |
20 | pub(crate) structs: LocationIntener<ItemLoc<ast::StructDef>, StructId>, | 20 | structs: LocationIntener<ItemLoc<ast::StructDef>, StructId>, |
21 | pub(crate) enums: LocationIntener<ItemLoc<ast::EnumDef>, EnumId>, | 21 | enums: LocationIntener<ItemLoc<ast::EnumDef>, EnumId>, |
22 | pub(crate) enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>, | 22 | enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>, |
23 | } | 23 | } |
24 | 24 | ||
25 | impl HirInterner { | 25 | impl HirInterner { |
@@ -144,50 +144,64 @@ pub struct ItemLoc<N: AstNode> { | |||
144 | _ty: PhantomData<N>, | 144 | _ty: PhantomData<N>, |
145 | } | 145 | } |
146 | 146 | ||
147 | impl<N: AstNode> ItemLoc<N> { | 147 | impl<N: AstNode> Clone for ItemLoc<N> { |
148 | pub(crate) fn from_ast( | 148 | fn clone(&self) -> ItemLoc<N> { |
149 | db: &impl HirDatabase, | ||
150 | module: Module, | ||
151 | file_id: HirFileId, | ||
152 | ast: &N, | ||
153 | ) -> ItemLoc<N> { | ||
154 | let items = db.file_items(file_id); | ||
155 | let raw = SourceItemId { | ||
156 | file_id, | ||
157 | item_id: Some(items.id_of(file_id, ast.syntax())), | ||
158 | }; | ||
159 | ItemLoc { | 149 | ItemLoc { |
160 | module, | 150 | module: self.module, |
161 | raw, | 151 | raw: self.raw, |
162 | _ty: PhantomData, | 152 | _ty: PhantomData, |
163 | } | 153 | } |
164 | } | 154 | } |
155 | } | ||
165 | 156 | ||
166 | pub(crate) fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<N>) { | 157 | #[derive(Clone, Copy)] |
167 | let syntax = db.file_item(self.raw); | 158 | pub(crate) struct LocationCtx<DB> { |
168 | let ast = N::cast(&syntax) | 159 | db: DB, |
169 | .unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", self.raw)) | 160 | module: Module, |
170 | .to_owned(); | 161 | file_id: HirFileId, |
171 | (self.raw.file_id, ast) | ||
172 | } | ||
173 | } | 162 | } |
174 | 163 | ||
175 | impl<N: AstNode> Clone for ItemLoc<N> { | 164 | impl<'a, DB: HirDatabase> LocationCtx<&'a DB> { |
176 | fn clone(&self) -> ItemLoc<N> { | 165 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { |
177 | ItemLoc { | 166 | LocationCtx { |
178 | module: self.module, | 167 | db, |
179 | raw: self.raw, | 168 | module, |
180 | _ty: PhantomData, | 169 | file_id, |
181 | } | 170 | } |
182 | } | 171 | } |
172 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF | ||
173 | where | ||
174 | N: AstNode + Eq + Hash, | ||
175 | DEF: AstItemDef<N>, | ||
176 | { | ||
177 | DEF::from_ast(self, ast) | ||
178 | } | ||
183 | } | 179 | } |
184 | 180 | ||
185 | pub(crate) trait AstItemDef<N: AstNode + Eq + Hash>: ArenaId + Clone { | 181 | pub(crate) trait AstItemDef<N: AstNode + Eq + Hash>: ArenaId + Clone { |
186 | fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; | 182 | fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; |
183 | fn from_ast(ctx: LocationCtx<&impl HirDatabase>, ast: &N) -> Self { | ||
184 | let items = ctx.db.file_items(ctx.file_id); | ||
185 | let raw = SourceItemId { | ||
186 | file_id: ctx.file_id, | ||
187 | item_id: Some(items.id_of(ctx.file_id, ast.syntax())), | ||
188 | }; | ||
189 | let loc = ItemLoc { | ||
190 | module: ctx.module, | ||
191 | raw, | ||
192 | _ty: PhantomData, | ||
193 | }; | ||
194 | |||
195 | Self::interner(ctx.db.as_ref()).loc2id(&loc) | ||
196 | } | ||
187 | fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<N>) { | 197 | fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<N>) { |
188 | let int = Self::interner(db.as_ref()); | 198 | let int = Self::interner(db.as_ref()); |
189 | let loc = int.id2loc(self); | 199 | let loc = int.id2loc(self); |
190 | loc.source(db) | 200 | let syntax = db.file_item(loc.raw); |
201 | let ast = N::cast(&syntax) | ||
202 | .unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)) | ||
203 | .to_owned(); | ||
204 | (loc.raw.file_id, ast) | ||
191 | } | 205 | } |
192 | fn module(self, db: &impl HirDatabase) -> Module { | 206 | fn module(self, db: &impl HirDatabase) -> Module { |
193 | let int = Self::interner(db.as_ref()); | 207 | let int = Self::interner(db.as_ref()); |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 274169f93..3df0d3a3b 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -9,6 +9,7 @@ use crate::{ | |||
9 | Function, HirFileId, | 9 | Function, HirFileId, |
10 | db::HirDatabase, | 10 | db::HirDatabase, |
11 | type_ref::TypeRef, | 11 | type_ref::TypeRef, |
12 | ids::LocationCtx, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | use crate::code_model_api::{Module, ModuleSource}; | 15 | use crate::code_model_api::{Module, ModuleSource}; |
@@ -72,13 +73,14 @@ impl ImplData { | |||
72 | ) -> Self { | 73 | ) -> Self { |
73 | let target_trait = node.target_trait().map(TypeRef::from_ast); | 74 | let target_trait = node.target_trait().map(TypeRef::from_ast); |
74 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 75 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
76 | let ctx = LocationCtx::new(db, module, file_id); | ||
75 | let items = if let Some(item_list) = node.item_list() { | 77 | let items = if let Some(item_list) = node.item_list() { |
76 | item_list | 78 | item_list |
77 | .impl_items() | 79 | .impl_items() |
78 | .map(|item_node| { | 80 | .map(|item_node| { |
79 | let kind = match item_node.kind() { | 81 | let kind = match item_node.kind() { |
80 | ast::ImplItemKind::FnDef(it) => { | 82 | ast::ImplItemKind::FnDef(it) => { |
81 | return ImplItem::Method(Function::from_ast(db, module, file_id, it)); | 83 | return ImplItem::Method(Function { id: ctx.to_def(it) }); |
82 | } | 84 | } |
83 | ast::ImplItemKind::ConstDef(..) => DefKind::Item, | 85 | ast::ImplItemKind::ConstDef(..) => DefKind::Item, |
84 | ast::ImplItemKind::TypeDef(..) => DefKind::Item, | 86 | ast::ImplItemKind::TypeDef(..) => DefKind::Item, |
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 435804e2d..0056bdd5a 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -11,6 +11,7 @@ use crate::{ | |||
11 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, | 11 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, |
12 | HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function, | 12 | HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, Function, |
13 | ModuleDef, Module, Struct, Enum, | 13 | ModuleDef, Module, Struct, Enum, |
14 | ids::LocationCtx, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 17 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -146,10 +147,11 @@ impl LoweredModule { | |||
146 | file_items: &SourceFileItems, | 147 | file_items: &SourceFileItems, |
147 | item: &ast::ModuleItem, | 148 | item: &ast::ModuleItem, |
148 | ) { | 149 | ) { |
150 | let ctx = LocationCtx::new(db, module, file_id); | ||
149 | let name = match item.kind() { | 151 | let name = match item.kind() { |
150 | ast::ModuleItemKind::StructDef(it) => { | 152 | ast::ModuleItemKind::StructDef(it) => { |
151 | if let Some(name) = it.name() { | 153 | if let Some(name) = it.name() { |
152 | let s = Struct::from_ast(db, module, file_id, it); | 154 | let s = Struct { id: ctx.to_def(it) }; |
153 | let s: ModuleDef = s.into(); | 155 | let s: ModuleDef = s.into(); |
154 | self.declarations.insert(name.as_name(), PerNs::both(s, s)); | 156 | self.declarations.insert(name.as_name(), PerNs::both(s, s)); |
155 | } | 157 | } |
@@ -157,7 +159,7 @@ impl LoweredModule { | |||
157 | } | 159 | } |
158 | ast::ModuleItemKind::EnumDef(it) => { | 160 | ast::ModuleItemKind::EnumDef(it) => { |
159 | if let Some(name) = it.name() { | 161 | if let Some(name) = it.name() { |
160 | let e = Enum::from_ast(db, module, file_id, it); | 162 | let e = Enum { id: ctx.to_def(it) }; |
161 | let e: ModuleDef = e.into(); | 163 | let e: ModuleDef = e.into(); |
162 | self.declarations.insert(name.as_name(), PerNs::types(e)); | 164 | self.declarations.insert(name.as_name(), PerNs::types(e)); |
163 | } | 165 | } |
@@ -165,7 +167,7 @@ impl LoweredModule { | |||
165 | } | 167 | } |
166 | ast::ModuleItemKind::FnDef(it) => { | 168 | ast::ModuleItemKind::FnDef(it) => { |
167 | if let Some(name) = it.name() { | 169 | if let Some(name) = it.name() { |
168 | let func = Function::from_ast(db, module, file_id, it); | 170 | let func = Function { id: ctx.to_def(it) }; |
169 | self.declarations | 171 | self.declarations |
170 | .insert(name.as_name(), PerNs::values(func.into())); | 172 | .insert(name.as_name(), PerNs::values(func.into())); |
171 | } | 173 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index d1bf163d1..ea8185853 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -15,6 +15,7 @@ use ra_syntax::{ | |||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Function, SourceItemId, ModuleDef, | 16 | HirDatabase, Function, SourceItemId, ModuleDef, |
17 | AsName, Module, | 17 | AsName, Module, |
18 | ids::LocationCtx, | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | /// Locates the module by `FileId`. Picks topmost module in the file. | 21 | /// Locates the module by `FileId`. Picks topmost module in the file. |
@@ -116,7 +117,10 @@ pub fn function_from_module( | |||
116 | ) -> Function { | 117 | ) -> Function { |
117 | let (file_id, _) = module.definition_source(db); | 118 | let (file_id, _) = module.definition_source(db); |
118 | let file_id = file_id.into(); | 119 | let file_id = file_id.into(); |
119 | Function::from_ast(db, module, file_id, fn_def) | 120 | let ctx = LocationCtx::new(db, module, file_id); |
121 | Function { | ||
122 | id: ctx.to_def(fn_def), | ||
123 | } | ||
120 | } | 124 | } |
121 | 125 | ||
122 | pub fn function_from_child_node( | 126 | pub fn function_from_child_node( |