diff options
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 73f1379f1..913341bd5 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,9 +1,11 @@ | |||
1 | use std::marker::PhantomData; | ||
2 | |||
1 | use ra_db::{LocationIntener, FileId}; | 3 | use ra_db::{LocationIntener, FileId}; |
2 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; | 4 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; |
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 5 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | 6 | ||
5 | use crate::{ | 7 | use crate::{ |
6 | HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, | 8 | HirDatabase, Def, Struct, Enum, EnumVariant, Crate, |
7 | Module, Trait, Type, Static, Const, | 9 | Module, Trait, Type, Static, Const, |
8 | }; | 10 | }; |
9 | 11 | ||
@@ -129,15 +131,56 @@ impl MacroCallLoc { | |||
129 | } | 131 | } |
130 | } | 132 | } |
131 | 133 | ||
134 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
135 | pub struct ItemLoc<N: AstNode> { | ||
136 | pub(crate) module: Module, | ||
137 | raw: SourceItemId, | ||
138 | _ty: PhantomData<N>, | ||
139 | } | ||
140 | |||
141 | impl<N: AstNode> ItemLoc<N> { | ||
142 | pub(crate) fn from_ast( | ||
143 | db: &impl HirDatabase, | ||
144 | module: Module, | ||
145 | file_id: HirFileId, | ||
146 | ast: &N, | ||
147 | ) -> ItemLoc<N> { | ||
148 | let items = db.file_items(file_id); | ||
149 | let raw = SourceItemId { | ||
150 | file_id, | ||
151 | item_id: Some(items.id_of(file_id, ast.syntax())), | ||
152 | }; | ||
153 | ItemLoc { | ||
154 | module, | ||
155 | raw, | ||
156 | _ty: PhantomData, | ||
157 | } | ||
158 | } | ||
159 | |||
160 | pub(crate) fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<N>) { | ||
161 | let syntax = db.file_item(self.raw); | ||
162 | let ast = N::cast(&syntax) | ||
163 | .unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", self.raw)) | ||
164 | .to_owned(); | ||
165 | (self.raw.file_id, ast) | ||
166 | } | ||
167 | } | ||
168 | |||
169 | impl<N: AstNode> Clone for ItemLoc<N> { | ||
170 | fn clone(&self) -> ItemLoc<N> { | ||
171 | ItemLoc { | ||
172 | module: self.module, | ||
173 | raw: self.raw, | ||
174 | _ty: PhantomData, | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
132 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 179 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
133 | pub struct FunctionId(RawId); | 180 | pub struct FunctionId(RawId); |
134 | impl_arena_id!(FunctionId); | 181 | impl_arena_id!(FunctionId); |
135 | 182 | ||
136 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 183 | pub(crate) type FunctionLoc = ItemLoc<ast::FnDef>; |
137 | pub struct FunctionLoc { | ||
138 | pub(crate) module: Module, | ||
139 | pub(crate) source_item_id: SourceItemId, | ||
140 | } | ||
141 | 184 | ||
142 | impl FunctionId { | 185 | impl FunctionId { |
143 | pub(crate) fn loc(self, db: &impl AsRef<HirInterner>) -> FunctionLoc { | 186 | pub(crate) fn loc(self, db: &impl AsRef<HirInterner>) -> FunctionLoc { |
@@ -196,10 +239,7 @@ impl DefId { | |||
196 | pub fn resolve(self, db: &impl HirDatabase) -> Def { | 239 | pub fn resolve(self, db: &impl HirDatabase) -> Def { |
197 | let loc = self.loc(db); | 240 | let loc = self.loc(db); |
198 | match loc.kind { | 241 | match loc.kind { |
199 | DefKind::Function => { | 242 | DefKind::Function => unreachable!(), |
200 | let function = Function::new(self); | ||
201 | Def::Function(function) | ||
202 | } | ||
203 | DefKind::Struct => { | 243 | DefKind::Struct => { |
204 | let struct_def = Struct::new(self); | 244 | let struct_def = Struct::new(self); |
205 | Def::Struct(struct_def) | 245 | Def::Struct(struct_def) |
@@ -243,12 +283,6 @@ impl DefId { | |||
243 | pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { | 283 | pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { |
244 | self.module(db).krate(db) | 284 | self.module(db).krate(db) |
245 | } | 285 | } |
246 | |||
247 | /// Returns the containing impl block, if this is an impl item. | ||
248 | pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> { | ||
249 | let module_impls = db.impls_in_module(self.loc(db).module); | ||
250 | ImplBlock::containing(module_impls, self) | ||
251 | } | ||
252 | } | 286 | } |
253 | 287 | ||
254 | impl DefLoc { | 288 | impl DefLoc { |