1 //! Complete fields in record literals and patterns.
2 use ide_db::SymbolKind;
3 use syntax::ast::{self, Expr};
6 context::{DotAccess, DotAccessKind, PatternContext},
7 CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
8 CompletionRelevancePostfixMatch, Completions,
11 pub(crate) fn complete_record_pattern_fields(
12 acc: &mut Completions,
13 ctx: &CompletionContext<'_>,
14 pattern_ctx: &PatternContext,
16 if let PatternContext { record_pat: Some(record_pat), .. } = pattern_ctx {
17 let ty = ctx.sema.type_of_pat(&ast::Pat::RecordPat(record_pat.clone()));
18 let missing_fields = match ty.as_ref().and_then(|t| t.original.as_adt()) {
19 Some(hir::Adt::Union(un)) => {
20 // ctx.sema.record_pat_missing_fields will always return
21 // an empty Vec on a union literal. This is normally
22 // reasonable, but here we'd like to present the full list
23 // of fields if the literal is empty.
24 let were_fields_specified =
25 record_pat.record_pat_field_list().and_then(|fl| fl.fields().next()).is_some();
27 match were_fields_specified {
28 false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
32 _ => ctx.sema.record_pattern_missing_fields(record_pat),
34 complete_fields(acc, ctx, missing_fields);
38 pub(crate) fn complete_record_expr_fields(
39 acc: &mut Completions,
40 ctx: &CompletionContext<'_>,
41 record_expr: &ast::RecordExpr,
44 let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
46 let missing_fields = match ty.as_ref().and_then(|t| t.original.as_adt()) {
47 Some(hir::Adt::Union(un)) => {
48 // ctx.sema.record_literal_missing_fields will always return
49 // an empty Vec on a union literal. This is normally
50 // reasonable, but here we'd like to present the full list
51 // of fields if the literal is empty.
52 let were_fields_specified =
53 record_expr.record_expr_field_list().and_then(|fl| fl.fields().next()).is_some();
55 match were_fields_specified {
56 false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
61 let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
63 if !missing_fields.is_empty() {
64 cov_mark::hit!(functional_update_field);
65 add_default_update(acc, ctx, ty);
68 cov_mark::hit!(functional_update_one_dot);
70 CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
71 item.insert_text(".");
78 complete_fields(acc, ctx, missing_fields);
81 pub(crate) fn add_default_update(
82 acc: &mut Completions,
83 ctx: &CompletionContext<'_>,
84 ty: Option<hir::TypeInfo>,
86 let default_trait = ctx.famous_defs().core_default_Default();
87 let impls_default_trait = default_trait
89 .map_or(false, |(default_trait, ty)| ty.original.impls_trait(ctx.db, default_trait, &[]));
90 if impls_default_trait {
91 // FIXME: This should make use of scope_def like completions so we get all the other goodies
92 // that is we should handle this like actually completing the default function
93 let completion_text = "..Default::default()";
94 let mut item = CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
96 completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
97 item.insert_text(completion_text).set_relevance(CompletionRelevance {
98 postfix_match: Some(CompletionRelevancePostfixMatch::Exact),
106 acc: &mut Completions,
107 ctx: &CompletionContext<'_>,
108 missing_fields: Vec<(hir::Field, hir::Type)>,
110 for (field, ty) in missing_fields {
116 kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal: false },
127 use crate::tests::check_edit;
130 fn literal_struct_completion_edit() {
134 struct FooDesc { pub bar: bool }
136 fn create_foo(foo_desc: &FooDesc) -> () { () }
139 let foo = create_foo(&$0);
143 struct FooDesc { pub bar: bool }
145 fn create_foo(foo_desc: &FooDesc) -> () { () }
148 let foo = create_foo(&FooDesc { bar: ${1:()} }$0);
155 fn literal_struct_impl_self_completion() {
176 Self { bar: ${1:()} }$0
186 pub struct Foo(pub u64);
190 fn new() -> submod::Foo {
197 pub struct Foo(pub u64);
201 fn new() -> submod::Foo {
210 fn literal_struct_completion_from_sub_modules() {
212 "submod::Struct {…}",
220 fn f() -> submod::Struct {
231 fn f() -> submod::Struct {
232 submod::Struct { a: ${1:()} }$0
239 fn literal_struct_complexion_module() {
244 pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
245 pub fn create_foo(foo_desc: &FooDesc) -> () { () }
251 let foo = create_foo(&$0);
256 pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
257 pub fn create_foo(foo_desc: &FooDesc) -> () { () }
263 let foo = create_foo(&FooDesc { six: ${1:()}, neuf: ${2:()}, bar: ${3:()} }$0);
270 fn default_completion_edit() {
272 "..Default::default()",
274 //- minicore: default
275 struct Struct { foo: u32, bar: usize }
277 impl Default for Struct {
278 fn default() -> Self {}
289 struct Struct { foo: u32, bar: usize }
291 impl Default for Struct {
292 fn default() -> Self {}
304 "..Default::default()",
306 //- minicore: default
307 struct Struct { foo: u32, bar: usize }
309 impl Default for Struct {
310 fn default() -> Self {}
321 struct Struct { foo: u32, bar: usize }
323 impl Default for Struct {
324 fn default() -> Self {}
336 "..Default::default()",
338 //- minicore: default
339 struct Struct { foo: u32, bar: usize }
341 impl Default for Struct {
342 fn default() -> Self {}
353 struct Struct { foo: u32, bar: usize }
355 impl Default for Struct {
356 fn default() -> Self {}