From 5471c1ef4b2fda2fbaa63f7d8404abf04a3e9da4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 11 Apr 2019 16:22:10 +0300 Subject: generalize SourceAnalyzer to handle all defs with bodies --- crates/ra_hir/src/code_model_api.rs | 8 +++++++ crates/ra_hir/src/source_binder.rs | 30 +++++++++++++++--------- crates/ra_ide_api/src/completion/complete_dot.rs | 24 +++++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) (limited to 'crates') 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 { db.body_hir(*self) } + pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc { + match *self { + DefWithBody::Const(ref c) => c.body_source_map(db), + DefWithBody::Function(ref f) => f.body_source_map(db), + DefWithBody::Static(ref s) => s.body_source_map(db), + } + } + /// Builds a resolver for code inside this item. pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 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::{ }; use crate::{ - HirDatabase, Function, Struct, Enum, Const, Static, Either, + HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, AsName, Module, HirFileId, Crate, Trait, Resolver, ids::LocationCtx, expr, AstId @@ -219,7 +219,7 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R .unwrap_or_default() } -pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { +fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { node.ancestors() .find_map(|node| { if ast::Expr::cast(node).is_some() || ast::Block::cast(node).is_some() { @@ -284,16 +284,24 @@ pub enum PathResolution { impl SourceAnalyzer { pub fn new(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> SourceAnalyzer { - let resolver = resolver_for_node(db, file_id, node); - let function = function_from_child_node(db, file_id, node); - if let Some(function) = function { - SourceAnalyzer { - resolver, - body_source_map: Some(function.body_source_map(db)), - infer: Some(function.infer(db)), + let def_with_body = node.ancestors().find_map(|node| { + if let Some(src) = ast::FnDef::cast(node) { + return function_from_source(db, file_id, src).map(DefWithBody::from); } - } else { - SourceAnalyzer { resolver, body_source_map: None, infer: None } + if let Some(src) = ast::StaticDef::cast(node) { + return static_from_source(db, file_id, src).map(DefWithBody::from); + } + if let Some(src) = ast::ConstDef::cast(node) { + return const_from_source(db, file_id, src).map(DefWithBody::from); + } + None + }); + SourceAnalyzer { + resolver: def_with_body + .map(|it| it.resolver(db)) + .unwrap_or_else(|| resolver_for_node(db, file_id, node)), + body_source_map: def_with_body.map(|it| it.body_source_map(db)), + infer: def_with_body.map(|it| it.infer(db)), } } 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 @@ -305,6 +305,30 @@ mod tests { kind: Method, detail: "pub fn blah(&self)" } +]"### + ); + } + + #[test] + fn test_completion_works_in_consts() { + assert_debug_snapshot_matches!( + do_ref_completion( + r" + struct A { the_field: u32 } + const X: u32 = { + A { the_field: 92 }.<|> + }; + ", + ), + @r###"[ + CompletionItem { + label: "the_field", + source_range: [106; 106), + delete: [106; 106), + insert: "the_field", + kind: Field, + detail: "u32" + } ]"### ); } -- cgit v1.2.3