diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 173 | ||||
-rw-r--r-- | crates/ra_hir/src/has_source.rs | 12 |
3 files changed, 75 insertions, 133 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index c013ff99b..c705d1630 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | per_ns::PerNs, | 11 | per_ns::PerNs, |
12 | resolver::HasResolver, | 12 | resolver::HasResolver, |
13 | type_ref::{Mutability, TypeRef}, | 13 | type_ref::{Mutability, TypeRef}, |
14 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, | 14 | AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, |
15 | LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, | 15 | LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, |
16 | StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, | 16 | StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, |
17 | }; | 17 | }; |
@@ -269,7 +269,7 @@ pub struct Struct { | |||
269 | 269 | ||
270 | impl Struct { | 270 | impl Struct { |
271 | pub fn module(self, db: &impl DefDatabase) -> Module { | 271 | pub fn module(self, db: &impl DefDatabase) -> Module { |
272 | Module { id: self.id.module(db) } | 272 | Module { id: self.id.lookup(db).container } |
273 | } | 273 | } |
274 | 274 | ||
275 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 275 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -290,7 +290,7 @@ impl Struct { | |||
290 | } | 290 | } |
291 | 291 | ||
292 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 292 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
293 | Type::from_def(db, self.id.module(db).krate, self.id) | 293 | Type::from_def(db, self.id.lookup(db).container.krate, self.id) |
294 | } | 294 | } |
295 | 295 | ||
296 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { | 296 | fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
@@ -309,11 +309,11 @@ impl Union { | |||
309 | } | 309 | } |
310 | 310 | ||
311 | pub fn module(self, db: &impl DefDatabase) -> Module { | 311 | pub fn module(self, db: &impl DefDatabase) -> Module { |
312 | Module { id: self.id.module(db) } | 312 | Module { id: self.id.lookup(db).container } |
313 | } | 313 | } |
314 | 314 | ||
315 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 315 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
316 | Type::from_def(db, self.id.module(db).krate, self.id) | 316 | Type::from_def(db, self.id.lookup(db).container.krate, self.id) |
317 | } | 317 | } |
318 | 318 | ||
319 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 319 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
@@ -337,7 +337,7 @@ pub struct Enum { | |||
337 | 337 | ||
338 | impl Enum { | 338 | impl Enum { |
339 | pub fn module(self, db: &impl DefDatabase) -> Module { | 339 | pub fn module(self, db: &impl DefDatabase) -> Module { |
340 | Module { id: self.id.module(db) } | 340 | Module { id: self.id.lookup(db).container } |
341 | } | 341 | } |
342 | 342 | ||
343 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 343 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -357,7 +357,7 @@ impl Enum { | |||
357 | } | 357 | } |
358 | 358 | ||
359 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 359 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
360 | Type::from_def(db, self.id.module(db).krate, self.id) | 360 | Type::from_def(db, self.id.lookup(db).container.krate, self.id) |
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
@@ -577,7 +577,7 @@ pub struct Trait { | |||
577 | 577 | ||
578 | impl Trait { | 578 | impl Trait { |
579 | pub fn module(self, db: &impl DefDatabase) -> Module { | 579 | pub fn module(self, db: &impl DefDatabase) -> Module { |
580 | Module { id: self.id.module(db) } | 580 | Module { id: self.id.lookup(db).container } |
581 | } | 581 | } |
582 | 582 | ||
583 | pub fn name(self, db: &impl DefDatabase) -> Name { | 583 | pub fn name(self, db: &impl DefDatabase) -> Name { |
@@ -809,7 +809,10 @@ impl ImplBlock { | |||
809 | let resolver = self.id.resolver(db); | 809 | let resolver = self.id.resolver(db); |
810 | let environment = TraitEnvironment::lower(db, &resolver); | 810 | let environment = TraitEnvironment::lower(db, &resolver); |
811 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | 811 | let ty = Ty::from_hir(db, &resolver, &impl_data.target_type); |
812 | Type { krate: self.id.module(db).krate, ty: InEnvironment { value: ty, environment } } | 812 | Type { |
813 | krate: self.id.lookup(db).container.krate, | ||
814 | ty: InEnvironment { value: ty, environment }, | ||
815 | } | ||
813 | } | 816 | } |
814 | 817 | ||
815 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 818 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
@@ -821,7 +824,7 @@ impl ImplBlock { | |||
821 | } | 824 | } |
822 | 825 | ||
823 | pub fn module(&self, db: &impl DefDatabase) -> Module { | 826 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
824 | self.id.module(db).into() | 827 | self.id.lookup(db).container.into() |
825 | } | 828 | } |
826 | 829 | ||
827 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | 830 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { |
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 307f3d5bf..7abb4bd75 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,7 +1,8 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | use hir_def::{ | 2 | use hir_def::{ |
3 | child_by_source::ChildBySource, dyn_map::DynMap, keys, nameres::ModuleSource, AstItemDef, | 3 | child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, |
4 | EnumVariantId, GenericDefId, LocationCtx, ModuleId, VariantId, | 4 | ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructId, |
5 | TraitId, TypeAliasId, UnionId, VariantId, | ||
5 | }; | 6 | }; |
6 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 7 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
7 | use ra_syntax::{ | 8 | use ra_syntax::{ |
@@ -20,74 +21,47 @@ pub trait FromSource: Sized { | |||
20 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; | 21 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; |
21 | } | 22 | } |
22 | 23 | ||
23 | impl FromSource for Struct { | 24 | pub trait FromSourceByContainer: Sized { |
24 | type Ast = ast::StructDef; | 25 | type Ast: AstNode + 'static; |
25 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 26 | type Id: Copy + 'static; |
26 | let id = from_source(db, src)?; | 27 | const KEY: Key<Self::Ast, Self::Id>; |
27 | Some(Struct { id }) | ||
28 | } | ||
29 | } | ||
30 | impl FromSource for Union { | ||
31 | type Ast = ast::UnionDef; | ||
32 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
33 | let id = from_source(db, src)?; | ||
34 | Some(Union { id }) | ||
35 | } | ||
36 | } | ||
37 | impl FromSource for Enum { | ||
38 | type Ast = ast::EnumDef; | ||
39 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
40 | let id = from_source(db, src)?; | ||
41 | Some(Enum { id }) | ||
42 | } | ||
43 | } | ||
44 | impl FromSource for Trait { | ||
45 | type Ast = ast::TraitDef; | ||
46 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
47 | let id = from_source(db, src)?; | ||
48 | Some(Trait { id }) | ||
49 | } | ||
50 | } | ||
51 | impl FromSource for Function { | ||
52 | type Ast = ast::FnDef; | ||
53 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
54 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::FUNCTION] | ||
55 | .get(&src) | ||
56 | .copied() | ||
57 | .map(Function::from) | ||
58 | } | ||
59 | } | 28 | } |
60 | 29 | ||
61 | impl FromSource for Const { | 30 | impl<T: FromSourceByContainer> FromSource for T |
62 | type Ast = ast::ConstDef; | 31 | where |
63 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 32 | T: From<<T as FromSourceByContainer>::Id>, |
64 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::CONST] | 33 | { |
65 | .get(&src) | 34 | type Ast = <T as FromSourceByContainer>::Ast; |
66 | .copied() | ||
67 | .map(Const::from) | ||
68 | } | ||
69 | } | ||
70 | impl FromSource for Static { | ||
71 | type Ast = ast::StaticDef; | ||
72 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 35 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
73 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::STATIC] | 36 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] |
74 | .get(&src) | 37 | .get(&src) |
75 | .copied() | 38 | .copied() |
76 | .map(Static::from) | 39 | .map(Self::from) |
77 | } | 40 | } |
78 | } | 41 | } |
79 | 42 | ||
80 | impl FromSource for TypeAlias { | 43 | macro_rules! from_source_by_container_impls { |
81 | type Ast = ast::TypeAliasDef; | 44 | ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$( |
82 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 45 | impl FromSourceByContainer for $hir { |
83 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db) | 46 | type Ast = $ast; |
84 | [keys::TYPE_ALIAS] | 47 | type Id = $id; |
85 | .get(&src) | 48 | const KEY: Key<Self::Ast, Self::Id> = $key; |
86 | .copied() | 49 | } |
87 | .map(TypeAlias::from) | 50 | )*} |
88 | } | ||
89 | } | 51 | } |
90 | 52 | ||
53 | from_source_by_container_impls![ | ||
54 | (Struct, StructId, ast::StructDef, keys::STRUCT), | ||
55 | (Union, UnionId, ast::UnionDef, keys::UNION), | ||
56 | (Enum, EnumId, ast::EnumDef, keys::ENUM), | ||
57 | (Trait, TraitId, ast::TraitDef, keys::TRAIT), | ||
58 | (Function, FunctionId, ast::FnDef, keys::FUNCTION), | ||
59 | (Static, StaticId, ast::StaticDef, keys::STATIC), | ||
60 | (Const, ConstId, ast::ConstDef, keys::CONST), | ||
61 | (TypeAlias, TypeAliasId, ast::TypeAliasDef, keys::TYPE_ALIAS), | ||
62 | (ImplBlock, ImplId, ast::ImplBlock, keys::IMPL), | ||
63 | ]; | ||
64 | |||
91 | impl FromSource for MacroDef { | 65 | impl FromSource for MacroDef { |
92 | type Ast = ast::MacroCall; | 66 | type Ast = ast::MacroCall; |
93 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 67 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
@@ -104,14 +78,6 @@ impl FromSource for MacroDef { | |||
104 | } | 78 | } |
105 | } | 79 | } |
106 | 80 | ||
107 | impl FromSource for ImplBlock { | ||
108 | type Ast = ast::ImplBlock; | ||
109 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
110 | let id = from_source(db, src)?; | ||
111 | Some(ImplBlock { id }) | ||
112 | } | ||
113 | } | ||
114 | |||
115 | impl FromSource for EnumVariant { | 81 | impl FromSource for EnumVariant { |
116 | type Ast = ast::EnumVariant; | 82 | type Ast = ast::EnumVariant; |
117 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 83 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
@@ -245,57 +211,30 @@ impl Module { | |||
245 | } | 211 | } |
246 | } | 212 | } |
247 | 213 | ||
248 | fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: InFile<N>) -> Option<DEF> | 214 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { |
249 | where | 215 | _analyze_container(db, src).unwrap_or_default() |
250 | N: AstNode, | ||
251 | DEF: AstItemDef<N>, | ||
252 | { | ||
253 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | ||
254 | let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?; | ||
255 | let ctx = LocationCtx::new(db, module.id, src.file_id); | ||
256 | let items = db.ast_id_map(src.file_id); | ||
257 | let item_id = items.ast_id(&src.value); | ||
258 | Some(DEF::from_ast_id(ctx, item_id)) | ||
259 | } | 216 | } |
260 | 217 | ||
261 | enum Container { | 218 | fn _analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { |
262 | Trait(Trait), | 219 | // FIXME: this doesn't try to handle nested declarations |
263 | ImplBlock(ImplBlock), | 220 | for container in src.value.ancestors().skip(1) { |
264 | Module(Module), | 221 | let res = match_ast! { |
265 | } | 222 | match container { |
266 | 223 | ast::TraitDef(it) => { | |
267 | impl Container { | 224 | let c = Trait::from_source(db, src.with_value(it))?; |
268 | fn find(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<Container> { | 225 | c.id.child_by_source(db) |
269 | // FIXME: this doesn't try to handle nested declarations | 226 | }, |
270 | for container in src.value.ancestors() { | 227 | ast::ImplBlock(it) => { |
271 | let res = match_ast! { | 228 | let c = ImplBlock::from_source(db, src.with_value(it))?; |
272 | match container { | 229 | c.id.child_by_source(db) |
273 | ast::TraitDef(it) => { | 230 | }, |
274 | let c = Trait::from_source(db, src.with_value(it))?; | 231 | _ => { continue }, |
275 | Container::Trait(c) | 232 | } |
276 | }, | 233 | }; |
277 | ast::ImplBlock(it) => { | 234 | return Some(res); |
278 | let c = ImplBlock::from_source(db, src.with_value(it))?; | ||
279 | Container::ImplBlock(c) | ||
280 | }, | ||
281 | _ => { continue }, | ||
282 | } | ||
283 | }; | ||
284 | return Some(res); | ||
285 | } | ||
286 | |||
287 | let module_source = ModuleSource::from_child_node(db, src); | ||
288 | let c = Module::from_definition(db, src.with_value(module_source))?; | ||
289 | Some(Container::Module(c)) | ||
290 | } | 235 | } |
291 | } | ||
292 | 236 | ||
293 | impl ChildBySource for Container { | 237 | let module_source = ModuleSource::from_child_node(db, src); |
294 | fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { | 238 | let c = Module::from_definition(db, src.with_value(module_source))?; |
295 | match self { | 239 | Some(c.id.child_by_source(db)) |
296 | Container::Trait(it) => it.id.child_by_source(db), | ||
297 | Container::ImplBlock(it) => it.id.child_by_source(db), | ||
298 | Container::Module(it) => it.id.child_by_source(db), | ||
299 | } | ||
300 | } | ||
301 | } | 240 | } |
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs index b09582f93..72afecf26 100644 --- a/crates/ra_hir/src/has_source.rs +++ b/crates/ra_hir/src/has_source.rs | |||
@@ -4,7 +4,7 @@ use either::Either; | |||
4 | use hir_def::{ | 4 | use hir_def::{ |
5 | nameres::ModuleSource, | 5 | nameres::ModuleSource, |
6 | src::{HasChildSource, HasSource as _}, | 6 | src::{HasChildSource, HasSource as _}, |
7 | AstItemDef, Lookup, VariantId, | 7 | Lookup, VariantId, |
8 | }; | 8 | }; |
9 | use ra_syntax::ast; | 9 | use ra_syntax::ast; |
10 | 10 | ||
@@ -51,19 +51,19 @@ impl HasSource for StructField { | |||
51 | impl HasSource for Struct { | 51 | impl HasSource for Struct { |
52 | type Ast = ast::StructDef; | 52 | type Ast = ast::StructDef; |
53 | fn source(self, db: &impl DefDatabase) -> InFile<ast::StructDef> { | 53 | fn source(self, db: &impl DefDatabase) -> InFile<ast::StructDef> { |
54 | self.id.source(db) | 54 | self.id.lookup(db).source(db) |
55 | } | 55 | } |
56 | } | 56 | } |
57 | impl HasSource for Union { | 57 | impl HasSource for Union { |
58 | type Ast = ast::UnionDef; | 58 | type Ast = ast::UnionDef; |
59 | fn source(self, db: &impl DefDatabase) -> InFile<ast::UnionDef> { | 59 | fn source(self, db: &impl DefDatabase) -> InFile<ast::UnionDef> { |
60 | self.id.source(db) | 60 | self.id.lookup(db).source(db) |
61 | } | 61 | } |
62 | } | 62 | } |
63 | impl HasSource for Enum { | 63 | impl HasSource for Enum { |
64 | type Ast = ast::EnumDef; | 64 | type Ast = ast::EnumDef; |
65 | fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumDef> { | 65 | fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumDef> { |
66 | self.id.source(db) | 66 | self.id.lookup(db).source(db) |
67 | } | 67 | } |
68 | } | 68 | } |
69 | impl HasSource for EnumVariant { | 69 | impl HasSource for EnumVariant { |
@@ -93,7 +93,7 @@ impl HasSource for Static { | |||
93 | impl HasSource for Trait { | 93 | impl HasSource for Trait { |
94 | type Ast = ast::TraitDef; | 94 | type Ast = ast::TraitDef; |
95 | fn source(self, db: &impl DefDatabase) -> InFile<ast::TraitDef> { | 95 | fn source(self, db: &impl DefDatabase) -> InFile<ast::TraitDef> { |
96 | self.id.source(db) | 96 | self.id.lookup(db).source(db) |
97 | } | 97 | } |
98 | } | 98 | } |
99 | impl HasSource for TypeAlias { | 99 | impl HasSource for TypeAlias { |
@@ -114,7 +114,7 @@ impl HasSource for MacroDef { | |||
114 | impl HasSource for ImplBlock { | 114 | impl HasSource for ImplBlock { |
115 | type Ast = ast::ImplBlock; | 115 | type Ast = ast::ImplBlock; |
116 | fn source(self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> { | 116 | fn source(self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> { |
117 | self.id.source(db) | 117 | self.id.lookup(db).source(db) |
118 | } | 118 | } |
119 | } | 119 | } |
120 | impl HasSource for Import { | 120 | impl HasSource for Import { |