From 65a2be49539375502ca95c8da455f50f580df2e3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Feb 2019 17:01:56 +0300 Subject: complete struct literals --- .../src/completion/complete_struct_literal.rs | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 crates/ra_ide_api/src/completion/complete_struct_literal.rs (limited to 'crates/ra_ide_api/src/completion/complete_struct_literal.rs') diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs new file mode 100644 index 000000000..893056c2b --- /dev/null +++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs @@ -0,0 +1,64 @@ +use hir::{Ty, AdtDef, Docs}; + +use crate::completion::{CompletionContext, Completions, CompletionItem, CompletionItemKind}; +use crate::completion::completion_item::CompletionKind; + +/// Complete dot accesses, i.e. fields or methods (currently only fields). +pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { + let (function, struct_lit) = match (&ctx.function, ctx.struct_lit_syntax) { + (Some(function), Some(struct_lit)) => (function, struct_lit), + _ => return, + }; + let infer_result = function.infer(ctx.db); + let syntax_mapping = function.body_syntax_mapping(ctx.db); + let expr = match syntax_mapping.node_expr(struct_lit.into()) { + Some(expr) => expr, + None => return, + }; + let ty = infer_result[expr].clone(); + let (adt, substs) = match ty { + Ty::Adt { def_id, ref substs, .. } => (def_id, substs), + _ => return, + }; + match adt { + AdtDef::Struct(s) => { + for field in s.fields(ctx.db) { + CompletionItem::new( + CompletionKind::Reference, + ctx.source_range(), + field.name(ctx.db).to_string(), + ) + .kind(CompletionItemKind::Field) + .detail(field.ty(ctx.db).subst(substs).to_string()) + .set_documentation(field.docs(ctx.db)) + .add_to(acc); + } + } + + // TODO unions + AdtDef::Enum(_) => (), + }; +} + +#[cfg(test)] +mod tests { + use crate::completion::*; + use crate::completion::completion_item::check_completion; + + fn check_ref_completion(name: &str, code: &str) { + check_completion(name, code, CompletionKind::Reference); + } + + #[test] + fn test_struct_literal_field() { + check_ref_completion( + "test_struct_literal_field", + r" + struct A { the_field: u32 } + fn foo() { + A { the<|> } + } + ", + ); + } +} -- cgit v1.2.3