aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/adt.rs54
-rw-r--r--crates/ra_hir/src/code_model_impl/function.rs14
-rw-r--r--crates/ra_hir/src/ids.rs78
-rw-r--r--crates/ra_hir/src/impl_block.rs4
-rw-r--r--crates/ra_hir/src/nameres/lower.rs8
-rw-r--r--crates/ra_hir/src/source_binder.rs6
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
10use crate::{ 10use 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
17impl Struct { 17impl 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
34impl 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)]
48pub struct StructData { 24pub 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
67impl 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)]
81pub struct EnumData { 44pub 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;
5use ra_syntax::ast::{self, NameOwner}; 5use ra_syntax::ast::{self, NameOwner};
6 6
7use crate::{ 7use 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
15pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax}; 14pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
16 15
17impl Function { 16impl 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::{
16pub struct HirInterner { 16pub 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
25impl HirInterner { 25impl HirInterner {
@@ -144,50 +144,64 @@ pub struct ItemLoc<N: AstNode> {
144 _ty: PhantomData<N>, 144 _ty: PhantomData<N>,
145} 145}
146 146
147impl<N: AstNode> ItemLoc<N> { 147impl<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); 158pub(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
175impl<N: AstNode> Clone for ItemLoc<N> { 164impl<'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
185pub(crate) trait AstItemDef<N: AstNode + Eq + Hash>: ArenaId + Clone { 181pub(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
14use crate::code_model_api::{Module, ModuleSource}; 15use 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::{
15use crate::{ 15use 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
122pub fn function_from_child_node( 126pub fn function_from_child_node(