diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 111 |
1 files changed, 34 insertions, 77 deletions
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f7411c5cf..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, EnumVariantId, | 3 | child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, |
4 | GenericDefId, 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,81 +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 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STRUCT] | 27 | const KEY: Key<Self::Ast, Self::Id>; |
27 | .get(&src) | ||
28 | .copied() | ||
29 | .map(Struct::from) | ||
30 | } | ||
31 | } | ||
32 | impl FromSource for Union { | ||
33 | type Ast = ast::UnionDef; | ||
34 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
35 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::UNION] | ||
36 | .get(&src) | ||
37 | .copied() | ||
38 | .map(Union::from) | ||
39 | } | ||
40 | } | ||
41 | impl FromSource for Enum { | ||
42 | type Ast = ast::EnumDef; | ||
43 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
44 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::ENUM] | ||
45 | .get(&src) | ||
46 | .copied() | ||
47 | .map(Enum::from) | ||
48 | } | ||
49 | } | ||
50 | impl FromSource for Trait { | ||
51 | type Ast = ast::TraitDef; | ||
52 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
53 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TRAIT] | ||
54 | .get(&src) | ||
55 | .copied() | ||
56 | .map(Trait::from) | ||
57 | } | ||
58 | } | ||
59 | impl FromSource for Function { | ||
60 | type Ast = ast::FnDef; | ||
61 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
62 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::FUNCTION] | ||
63 | .get(&src) | ||
64 | .copied() | ||
65 | .map(Function::from) | ||
66 | } | ||
67 | } | 28 | } |
68 | 29 | ||
69 | impl FromSource for Const { | 30 | impl<T: FromSourceByContainer> FromSource for T |
70 | type Ast = ast::ConstDef; | 31 | where |
71 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 32 | T: From<<T as FromSourceByContainer>::Id>, |
72 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::CONST] | 33 | { |
73 | .get(&src) | 34 | type Ast = <T as FromSourceByContainer>::Ast; |
74 | .copied() | ||
75 | .map(Const::from) | ||
76 | } | ||
77 | } | ||
78 | impl FromSource for Static { | ||
79 | type Ast = ast::StaticDef; | ||
80 | 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> { |
81 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STATIC] | 36 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] |
82 | .get(&src) | 37 | .get(&src) |
83 | .copied() | 38 | .copied() |
84 | .map(Static::from) | 39 | .map(Self::from) |
85 | } | 40 | } |
86 | } | 41 | } |
87 | 42 | ||
88 | impl FromSource for TypeAlias { | 43 | macro_rules! from_source_by_container_impls { |
89 | type Ast = ast::TypeAliasDef; | 44 | ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$( |
90 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 45 | impl FromSourceByContainer for $hir { |
91 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TYPE_ALIAS] | 46 | type Ast = $ast; |
92 | .get(&src) | 47 | type Id = $id; |
93 | .copied() | 48 | const KEY: Key<Self::Ast, Self::Id> = $key; |
94 | .map(TypeAlias::from) | 49 | } |
95 | } | 50 | )*} |
96 | } | 51 | } |
97 | 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 | |||
98 | impl FromSource for MacroDef { | 65 | impl FromSource for MacroDef { |
99 | type Ast = ast::MacroCall; | 66 | type Ast = ast::MacroCall; |
100 | 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> { |
@@ -111,16 +78,6 @@ impl FromSource for MacroDef { | |||
111 | } | 78 | } |
112 | } | 79 | } |
113 | 80 | ||
114 | impl FromSource for ImplBlock { | ||
115 | type Ast = ast::ImplBlock; | ||
116 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | ||
117 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::IMPL] | ||
118 | .get(&src) | ||
119 | .copied() | ||
120 | .map(ImplBlock::from) | ||
121 | } | ||
122 | } | ||
123 | |||
124 | impl FromSource for EnumVariant { | 81 | impl FromSource for EnumVariant { |
125 | type Ast = ast::EnumVariant; | 82 | type Ast = ast::EnumVariant; |
126 | 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> { |