aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/fill_struct_fields.rs58
1 files changed, 45 insertions, 13 deletions
diff --git a/crates/ra_assists/src/fill_struct_fields.rs b/crates/ra_assists/src/fill_struct_fields.rs
index 938322d1d..90ce9c577 100644
--- a/crates/ra_assists/src/fill_struct_fields.rs
+++ b/crates/ra_assists/src/fill_struct_fields.rs
@@ -3,39 +3,34 @@ use std::fmt::Write;
3use hir::{AdtDef, Ty, source_binder}; 3use hir::{AdtDef, Ty, source_binder};
4use hir::db::HirDatabase; 4use hir::db::HirDatabase;
5 5
6use ra_syntax::ast::{self, AstNode, Expr}; 6use ra_syntax::ast::{self, AstNode};
7 7
8use crate::{AssistCtx, Assist, AssistId}; 8use crate::{AssistCtx, Assist, AssistId};
9 9
10pub(crate) fn fill_struct_fields(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 10pub(crate) fn fill_struct_fields(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
11 let struct_lit = ctx.node_at_offset::<ast::StructLit>()?; 11 let struct_lit = ctx.node_at_offset::<ast::StructLit>()?;
12 let named_field_list = struct_lit.named_field_list()?;
12 13
13 // If we already have existing struct fields, don't provide the assist. 14 // If we already have existing struct fields, don't provide the assist.
14 match struct_lit.named_field_list() { 15 if named_field_list.fields().count() > 0 {
15 Some(named_field_list) if named_field_list.fields().count() > 0 => { 16 return None;
16 return None;
17 }
18 _ => {}
19 } 17 }
20 18
21 let expr: &Expr = struct_lit.into();
22 let function = 19 let function =
23 source_binder::function_from_child_node(ctx.db, ctx.frange.file_id, struct_lit.syntax())?; 20 source_binder::function_from_child_node(ctx.db, ctx.frange.file_id, struct_lit.syntax())?;
24 21
25 let infer_result = function.infer(ctx.db); 22 let infer_result = function.infer(ctx.db);
26 let source_map = function.body_source_map(ctx.db); 23 let source_map = function.body_source_map(ctx.db);
27 let node_expr = source_map.node_expr(expr)?; 24 let node_expr = source_map.node_expr(struct_lit.into())?;
28 let struct_lit_ty = infer_result[node_expr].clone(); 25 let struct_lit_ty = infer_result[node_expr].clone();
29 let struct_def = match struct_lit_ty { 26 let struct_def = match struct_lit_ty {
30 Ty::Adt { def_id: AdtDef::Struct(s), .. } => s, 27 Ty::Adt { def_id: AdtDef::Struct(s), .. } => s,
31 _ => return None, 28 _ => return None,
32 }; 29 };
33 30
34 let struct_name = struct_def.name(ctx.db)?;
35 let db = ctx.db; 31 let db = ctx.db;
36
37 ctx.add_action(AssistId("fill_struct_fields"), "fill struct fields", |edit| { 32 ctx.add_action(AssistId("fill_struct_fields"), "fill struct fields", |edit| {
38 let mut buf = format!("{} {{\n", struct_name); 33 let mut buf = String::from("{\n");
39 let struct_fields = struct_def.fields(db); 34 let struct_fields = struct_def.fields(db);
40 for field in struct_fields { 35 for field in struct_fields {
41 let field_name = field.name(db).to_string(); 36 let field_name = field.name(db).to_string();
@@ -44,8 +39,8 @@ pub(crate) fn fill_struct_fields(mut ctx: AssistCtx<impl HirDatabase>) -> Option
44 buf.push_str("}"); 39 buf.push_str("}");
45 40
46 edit.target(struct_lit.syntax().range()); 41 edit.target(struct_lit.syntax().range());
47 edit.set_cursor(expr.syntax().range().start()); 42 edit.set_cursor(struct_lit.syntax().range().start());
48 edit.replace_node_and_indent(struct_lit.syntax(), buf); 43 edit.replace_node_and_indent(named_field_list.syntax(), buf);
49 }); 44 });
50 45
51 ctx.build() 46 ctx.build()
@@ -116,4 +111,41 @@ mod tests {
116 "S {}", 111 "S {}",
117 ); 112 );
118 } 113 }
114
115 #[test]
116 fn fill_struct_fields_preserve_self() {
117 check_assist(
118 fill_struct_fields,
119 r#"
120 struct Foo {
121 foo: u8,
122 bar: String,
123 baz: i128,
124 }
125
126 impl Foo {
127 pub fn new() -> Self {
128 Self <|>{}
129 }
130 }
131 "#,
132 r#"
133 struct Foo {
134 foo: u8,
135 bar: String,
136 baz: i128,
137 }
138
139 impl Foo {
140 pub fn new() -> Self {
141 <|>Self {
142 foo: (),
143 bar: (),
144 baz: (),
145 }
146 }
147 }
148 "#,
149 );
150 }
119} 151}