From 2a1e11b36fe90460b139f2f6aee034f63e8252bf Mon Sep 17 00:00:00 2001 From: Ekaterina Babshukova Date: Fri, 12 Jul 2019 19:56:18 +0300 Subject: complete fields in enum variants --- .../src/completion/complete_struct_literal.rs | 103 ++++++++++++++++++--- 1 file changed, 88 insertions(+), 15 deletions(-) (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 index 35fb21113..b6216f857 100644 --- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs @@ -1,28 +1,24 @@ -use hir::AdtDef; +use hir::{Substs, Ty}; use crate::completion::{CompletionContext, Completions}; /// Complete fields in fields literals. pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { - let ty = match ctx.struct_lit_syntax.and_then(|it| ctx.analyzer.type_of(ctx.db, it.into())) { + let (ty, variant) = match ctx.struct_lit_syntax.and_then(|it| { + Some((ctx.analyzer.type_of(ctx.db, it.into())?, ctx.analyzer.resolve_variant(it)?)) + }) { Some(it) => it, - None => return, - }; - let (adt, substs) = match ty.as_adt() { - Some(res) => res, _ => return, }; - match adt { - AdtDef::Struct(s) => { - for field in s.fields(ctx.db) { - acc.add_field(ctx, field, substs); - } - } - // FIXME unions - AdtDef::Union(_) => (), - AdtDef::Enum(_) => (), + let ty_substs = match ty { + Ty::Apply(it) => it.parameters, + _ => Substs::empty(), }; + + for field in variant.fields(ctx.db) { + acc.add_field(ctx, field, &ty_substs); + } } #[cfg(test)] @@ -57,4 +53,81 @@ mod tests { ⋮] "###); } + + #[test] + fn test_struct_literal_enum_variant() { + let completions = complete( + r" + enum E { + A { a: u32 } + } + fn foo() { + let _ = E::A { <|> } + } + ", + ); + assert_debug_snapshot_matches!(completions, @r###" + ⋮[ + ⋮ CompletionItem { + ⋮ label: "a", + ⋮ source_range: [119; 119), + ⋮ delete: [119; 119), + ⋮ insert: "a", + ⋮ kind: Field, + ⋮ detail: "u32", + ⋮ }, + ⋮] + "###); + } + + #[test] + fn test_struct_literal_two_structs() { + let completions = complete( + r" + struct A { a: u32 } + struct B { b: u32 } + + fn foo() { + let _: A = B { <|> } + } + ", + ); + assert_debug_snapshot_matches!(completions, @r###" + ⋮[ + ⋮ CompletionItem { + ⋮ label: "b", + ⋮ source_range: [119; 119), + ⋮ delete: [119; 119), + ⋮ insert: "b", + ⋮ kind: Field, + ⋮ detail: "u32", + ⋮ }, + ⋮] + "###); + } + + #[test] + fn test_struct_literal_generic_struct() { + let completions = complete( + r" + struct A { a: T } + + fn foo() { + let _: A = A { <|> } + } + ", + ); + assert_debug_snapshot_matches!(completions, @r###" + ⋮[ + ⋮ CompletionItem { + ⋮ label: "a", + ⋮ source_range: [93; 93), + ⋮ delete: [93; 93), + ⋮ insert: "a", + ⋮ kind: Field, + ⋮ detail: "u32", + ⋮ }, + ⋮] + "###); + } } -- cgit v1.2.3