diff options
author | Aleksey Kladov <[email protected]> | 2019-04-11 14:22:10 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-04-11 14:37:29 +0100 |
commit | 5471c1ef4b2fda2fbaa63f7d8404abf04a3e9da4 (patch) | |
tree | b5a77b6b7474e728f5884969b41f53f0c2ebceb2 /crates | |
parent | 07cc047b4ffe3049dfe95fc5cd59383336976e2d (diff) |
generalize SourceAnalyzer to handle all defs with bodies
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 30 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_dot.rs | 24 |
3 files changed, 51 insertions, 11 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 660edf006..40bfd5faf 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -454,6 +454,14 @@ impl DefWithBody { | |||
454 | db.body_hir(*self) | 454 | db.body_hir(*self) |
455 | } | 455 | } |
456 | 456 | ||
457 | pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
458 | match *self { | ||
459 | DefWithBody::Const(ref c) => c.body_source_map(db), | ||
460 | DefWithBody::Function(ref f) => f.body_source_map(db), | ||
461 | DefWithBody::Static(ref s) => s.body_source_map(db), | ||
462 | } | ||
463 | } | ||
464 | |||
457 | /// Builds a resolver for code inside this item. | 465 | /// Builds a resolver for code inside this item. |
458 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 466 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
459 | match *self { | 467 | match *self { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index ec9af035f..dc9d614c0 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -15,7 +15,7 @@ use ra_syntax::{ | |||
15 | }; | 15 | }; |
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | HirDatabase, Function, Struct, Enum, Const, Static, Either, | 18 | HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, |
19 | AsName, Module, HirFileId, Crate, Trait, Resolver, | 19 | AsName, Module, HirFileId, Crate, Trait, Resolver, |
20 | ids::LocationCtx, | 20 | ids::LocationCtx, |
21 | expr, AstId | 21 | expr, AstId |
@@ -219,7 +219,7 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R | |||
219 | .unwrap_or_default() | 219 | .unwrap_or_default() |
220 | } | 220 | } |
221 | 221 | ||
222 | pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { | 222 | fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { |
223 | node.ancestors() | 223 | node.ancestors() |
224 | .find_map(|node| { | 224 | .find_map(|node| { |
225 | if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { | 225 | if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { |
@@ -284,16 +284,24 @@ pub enum PathResolution { | |||
284 | 284 | ||
285 | impl SourceAnalyzer { | 285 | impl SourceAnalyzer { |
286 | pub fn new(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> SourceAnalyzer { | 286 | pub fn new(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> SourceAnalyzer { |
287 | let resolver = resolver_for_node(db, file_id, node); | 287 | let def_with_body = node.ancestors().find_map(|node| { |
288 | let function = function_from_child_node(db, file_id, node); | 288 | if let Some(src) = ast::FnDef::cast(node) { |
289 | if let Some(function) = function { | 289 | return function_from_source(db, file_id, src).map(DefWithBody::from); |
290 | SourceAnalyzer { | ||
291 | resolver, | ||
292 | body_source_map: Some(function.body_source_map(db)), | ||
293 | infer: Some(function.infer(db)), | ||
294 | } | 290 | } |
295 | } else { | 291 | if let Some(src) = ast::StaticDef::cast(node) { |
296 | SourceAnalyzer { resolver, body_source_map: None, infer: None } | 292 | return static_from_source(db, file_id, src).map(DefWithBody::from); |
293 | } | ||
294 | if let Some(src) = ast::ConstDef::cast(node) { | ||
295 | return const_from_source(db, file_id, src).map(DefWithBody::from); | ||
296 | } | ||
297 | None | ||
298 | }); | ||
299 | SourceAnalyzer { | ||
300 | resolver: def_with_body | ||
301 | .map(|it| it.resolver(db)) | ||
302 | .unwrap_or_else(|| resolver_for_node(db, file_id, node)), | ||
303 | body_source_map: def_with_body.map(|it| it.body_source_map(db)), | ||
304 | infer: def_with_body.map(|it| it.infer(db)), | ||
297 | } | 305 | } |
298 | } | 306 | } |
299 | 307 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 358057364..4a111aba5 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -308,4 +308,28 @@ mod tests { | |||
308 | ]"### | 308 | ]"### |
309 | ); | 309 | ); |
310 | } | 310 | } |
311 | |||
312 | #[test] | ||
313 | fn test_completion_works_in_consts() { | ||
314 | assert_debug_snapshot_matches!( | ||
315 | do_ref_completion( | ||
316 | r" | ||
317 | struct A { the_field: u32 } | ||
318 | const X: u32 = { | ||
319 | A { the_field: 92 }.<|> | ||
320 | }; | ||
321 | ", | ||
322 | ), | ||
323 | @r###"[ | ||
324 | CompletionItem { | ||
325 | label: "the_field", | ||
326 | source_range: [106; 106), | ||
327 | delete: [106; 106), | ||
328 | insert: "the_field", | ||
329 | kind: Field, | ||
330 | detail: "u32" | ||
331 | } | ||
332 | ]"### | ||
333 | ); | ||
334 | } | ||
311 | } | 335 | } |