diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 83 |
1 files changed, 34 insertions, 49 deletions
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 0cf4bcae1..091349d49 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -44,16 +44,16 @@ impl FromSource for Enum { | |||
44 | impl FromSource for Trait { | 44 | impl FromSource for Trait { |
45 | type Ast = ast::TraitDef; | 45 | type Ast = ast::TraitDef; |
46 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 46 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
47 | // XXX: use `.parent()` to avoid finding ourselves | 47 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TRAIT] |
48 | let parent = src.value.syntax().parent()?; | 48 | .get(&src) |
49 | let container = Container::find(db, src.with_value(parent).as_ref())?; | 49 | .copied() |
50 | container.child_by_source(db)[keys::TRAIT].get(&src).copied().map(Trait::from) | 50 | .map(Trait::from) |
51 | } | 51 | } |
52 | } | 52 | } |
53 | impl FromSource for Function { | 53 | impl FromSource for Function { |
54 | type Ast = ast::FnDef; | 54 | type Ast = ast::FnDef; |
55 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 55 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
56 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::FUNCTION] | 56 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::FUNCTION] |
57 | .get(&src) | 57 | .get(&src) |
58 | .copied() | 58 | .copied() |
59 | .map(Function::from) | 59 | .map(Function::from) |
@@ -63,7 +63,7 @@ impl FromSource for Function { | |||
63 | impl FromSource for Const { | 63 | impl FromSource for Const { |
64 | type Ast = ast::ConstDef; | 64 | type Ast = ast::ConstDef; |
65 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 65 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
66 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::CONST] | 66 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::CONST] |
67 | .get(&src) | 67 | .get(&src) |
68 | .copied() | 68 | .copied() |
69 | .map(Const::from) | 69 | .map(Const::from) |
@@ -72,7 +72,7 @@ impl FromSource for Const { | |||
72 | impl FromSource for Static { | 72 | impl FromSource for Static { |
73 | type Ast = ast::StaticDef; | 73 | type Ast = ast::StaticDef; |
74 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 74 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
75 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db)[keys::STATIC] | 75 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::STATIC] |
76 | .get(&src) | 76 | .get(&src) |
77 | .copied() | 77 | .copied() |
78 | .map(Static::from) | 78 | .map(Static::from) |
@@ -82,8 +82,7 @@ impl FromSource for Static { | |||
82 | impl FromSource for TypeAlias { | 82 | impl FromSource for TypeAlias { |
83 | type Ast = ast::TypeAliasDef; | 83 | type Ast = ast::TypeAliasDef; |
84 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 84 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
85 | Container::find(db, src.as_ref().map(|it| it.syntax()))?.child_by_source(db) | 85 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::TYPE_ALIAS] |
86 | [keys::TYPE_ALIAS] | ||
87 | .get(&src) | 86 | .get(&src) |
88 | .copied() | 87 | .copied() |
89 | .map(TypeAlias::from) | 88 | .map(TypeAlias::from) |
@@ -109,10 +108,10 @@ impl FromSource for MacroDef { | |||
109 | impl FromSource for ImplBlock { | 108 | impl FromSource for ImplBlock { |
110 | type Ast = ast::ImplBlock; | 109 | type Ast = ast::ImplBlock; |
111 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 110 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { |
112 | // XXX: use `.parent()` to avoid finding ourselves | 111 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[keys::IMPL] |
113 | let parent = src.value.syntax().parent()?; | 112 | .get(&src) |
114 | let container = Container::find(db, src.with_value(parent).as_ref())?; | 113 | .copied() |
115 | container.child_by_source(db)[keys::IMPL].get(&src).copied().map(ImplBlock::from) | 114 | .map(ImplBlock::from) |
116 | } | 115 | } |
117 | } | 116 | } |
118 | 117 | ||
@@ -262,44 +261,30 @@ where | |||
262 | Some(DEF::from_ast_id(ctx, item_id)) | 261 | Some(DEF::from_ast_id(ctx, item_id)) |
263 | } | 262 | } |
264 | 263 | ||
265 | enum Container { | 264 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { |
266 | Trait(Trait), | 265 | _analyze_container(db, src).unwrap_or_default() |
267 | ImplBlock(ImplBlock), | ||
268 | Module(Module), | ||
269 | } | 266 | } |
270 | 267 | ||
271 | impl Container { | 268 | fn _analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { |
272 | fn find(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<Container> { | 269 | // FIXME: this doesn't try to handle nested declarations |
273 | // FIXME: this doesn't try to handle nested declarations | 270 | for container in src.value.ancestors().skip(1) { |
274 | for container in src.value.ancestors() { | 271 | let res = match_ast! { |
275 | let res = match_ast! { | 272 | match container { |
276 | match container { | 273 | ast::TraitDef(it) => { |
277 | ast::TraitDef(it) => { | 274 | let c = Trait::from_source(db, src.with_value(it))?; |
278 | let c = Trait::from_source(db, src.with_value(it))?; | 275 | c.id.child_by_source(db) |
279 | Container::Trait(c) | 276 | }, |
280 | }, | 277 | ast::ImplBlock(it) => { |
281 | ast::ImplBlock(it) => { | 278 | let c = ImplBlock::from_source(db, src.with_value(it))?; |
282 | let c = ImplBlock::from_source(db, src.with_value(it))?; | 279 | c.id.child_by_source(db) |
283 | Container::ImplBlock(c) | 280 | }, |
284 | }, | 281 | _ => { continue }, |
285 | _ => { continue }, | 282 | } |
286 | } | 283 | }; |
287 | }; | 284 | return Some(res); |
288 | return Some(res); | ||
289 | } | ||
290 | |||
291 | let module_source = ModuleSource::from_child_node(db, src); | ||
292 | let c = Module::from_definition(db, src.with_value(module_source))?; | ||
293 | Some(Container::Module(c)) | ||
294 | } | 285 | } |
295 | } | ||
296 | 286 | ||
297 | impl ChildBySource for Container { | 287 | let module_source = ModuleSource::from_child_node(db, src); |
298 | fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { | 288 | let c = Module::from_definition(db, src.with_value(module_source))?; |
299 | match self { | 289 | Some(c.id.child_by_source(db)) |
300 | Container::Trait(it) => it.id.child_by_source(db), | ||
301 | Container::ImplBlock(it) => it.id.child_by_source(db), | ||
302 | Container::Module(it) => it.id.child_by_source(db), | ||
303 | } | ||
304 | } | ||
305 | } | 290 | } |