aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model.rs23
-rw-r--r--crates/ra_hir/src/from_source.rs173
-rw-r--r--crates/ra_hir/src/has_source.rs12
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
270impl Struct { 270impl 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
338impl Enum { 338impl 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
578impl Trait { 578impl 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
2use hir_def::{ 2use 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};
6use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 7use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
7use ra_syntax::{ 8use 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
23impl FromSource for Struct { 24pub 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}
30impl 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}
37impl 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}
44impl 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}
51impl 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
61impl FromSource for Const { 30impl<T: FromSourceByContainer> FromSource for T
62 type Ast = ast::ConstDef; 31where
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}
70impl 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
80impl FromSource for TypeAlias { 43macro_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
53from_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
91impl FromSource for MacroDef { 65impl 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
107impl 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
115impl FromSource for EnumVariant { 81impl 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
248fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: InFile<N>) -> Option<DEF> 214fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap {
249where 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
261enum Container { 218fn _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) => {
267impl 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
293impl 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;
4use hir_def::{ 4use 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};
9use ra_syntax::ast; 9use ra_syntax::ast;
10 10
@@ -51,19 +51,19 @@ impl HasSource for StructField {
51impl HasSource for Struct { 51impl 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}
57impl HasSource for Union { 57impl 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}
63impl HasSource for Enum { 63impl 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}
69impl HasSource for EnumVariant { 69impl HasSource for EnumVariant {
@@ -93,7 +93,7 @@ impl HasSource for Static {
93impl HasSource for Trait { 93impl 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}
99impl HasSource for TypeAlias { 99impl HasSource for TypeAlias {
@@ -114,7 +114,7 @@ impl HasSource for MacroDef {
114impl HasSource for ImplBlock { 114impl 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}
120impl HasSource for Import { 120impl HasSource for Import {