aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ids.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r--crates/ra_hir/src/ids.rs78
1 files changed, 46 insertions, 32 deletions
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());