aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-04-11 14:22:10 +0100
committerAleksey Kladov <[email protected]>2019-04-11 14:37:29 +0100
commit5471c1ef4b2fda2fbaa63f7d8404abf04a3e9da4 (patch)
treeb5a77b6b7474e728f5884969b41f53f0c2ebceb2 /crates
parent07cc047b4ffe3049dfe95fc5cd59383336976e2d (diff)
generalize SourceAnalyzer to handle all defs with bodies
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model_api.rs8
-rw-r--r--crates/ra_hir/src/source_binder.rs30
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs24
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
17use crate::{ 17use 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
222pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNode) -> Resolver { 222fn 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
285impl SourceAnalyzer { 285impl 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}