mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 07:04:49 +00:00
Only replace NamedFieldList and add test for preserving Self
This commit is contained in:
parent
8d47e004b8
commit
ca262fbab8
1 changed files with 45 additions and 13 deletions
|
@ -3,39 +3,34 @@ use std::fmt::Write;
|
||||||
use hir::{AdtDef, Ty, source_binder};
|
use hir::{AdtDef, Ty, source_binder};
|
||||||
use hir::db::HirDatabase;
|
use hir::db::HirDatabase;
|
||||||
|
|
||||||
use ra_syntax::ast::{self, AstNode, Expr};
|
use ra_syntax::ast::{self, AstNode};
|
||||||
|
|
||||||
use crate::{AssistCtx, Assist, AssistId};
|
use crate::{AssistCtx, Assist, AssistId};
|
||||||
|
|
||||||
pub(crate) fn fill_struct_fields(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
pub(crate) fn fill_struct_fields(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
||||||
let struct_lit = ctx.node_at_offset::<ast::StructLit>()?;
|
let struct_lit = ctx.node_at_offset::<ast::StructLit>()?;
|
||||||
|
let named_field_list = struct_lit.named_field_list()?;
|
||||||
|
|
||||||
// If we already have existing struct fields, don't provide the assist.
|
// If we already have existing struct fields, don't provide the assist.
|
||||||
match struct_lit.named_field_list() {
|
if named_field_list.fields().count() > 0 {
|
||||||
Some(named_field_list) if named_field_list.fields().count() > 0 => {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
let expr: &Expr = struct_lit.into();
|
|
||||||
let function =
|
let function =
|
||||||
source_binder::function_from_child_node(ctx.db, ctx.frange.file_id, struct_lit.syntax())?;
|
source_binder::function_from_child_node(ctx.db, ctx.frange.file_id, struct_lit.syntax())?;
|
||||||
|
|
||||||
let infer_result = function.infer(ctx.db);
|
let infer_result = function.infer(ctx.db);
|
||||||
let source_map = function.body_source_map(ctx.db);
|
let source_map = function.body_source_map(ctx.db);
|
||||||
let node_expr = source_map.node_expr(expr)?;
|
let node_expr = source_map.node_expr(struct_lit.into())?;
|
||||||
let struct_lit_ty = infer_result[node_expr].clone();
|
let struct_lit_ty = infer_result[node_expr].clone();
|
||||||
let struct_def = match struct_lit_ty {
|
let struct_def = match struct_lit_ty {
|
||||||
Ty::Adt { def_id: AdtDef::Struct(s), .. } => s,
|
Ty::Adt { def_id: AdtDef::Struct(s), .. } => s,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let struct_name = struct_def.name(ctx.db)?;
|
|
||||||
let db = ctx.db;
|
let db = ctx.db;
|
||||||
|
|
||||||
ctx.add_action(AssistId("fill_struct_fields"), "fill struct fields", |edit| {
|
ctx.add_action(AssistId("fill_struct_fields"), "fill struct fields", |edit| {
|
||||||
let mut buf = format!("{} {{\n", struct_name);
|
let mut buf = String::from("{\n");
|
||||||
let struct_fields = struct_def.fields(db);
|
let struct_fields = struct_def.fields(db);
|
||||||
for field in struct_fields {
|
for field in struct_fields {
|
||||||
let field_name = field.name(db).to_string();
|
let field_name = field.name(db).to_string();
|
||||||
|
@ -44,8 +39,8 @@ pub(crate) fn fill_struct_fields(mut ctx: AssistCtx<impl HirDatabase>) -> Option
|
||||||
buf.push_str("}");
|
buf.push_str("}");
|
||||||
|
|
||||||
edit.target(struct_lit.syntax().range());
|
edit.target(struct_lit.syntax().range());
|
||||||
edit.set_cursor(expr.syntax().range().start());
|
edit.set_cursor(struct_lit.syntax().range().start());
|
||||||
edit.replace_node_and_indent(struct_lit.syntax(), buf);
|
edit.replace_node_and_indent(named_field_list.syntax(), buf);
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.build()
|
ctx.build()
|
||||||
|
@ -116,4 +111,41 @@ mod tests {
|
||||||
"S {}",
|
"S {}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fill_struct_fields_preserve_self() {
|
||||||
|
check_assist(
|
||||||
|
fill_struct_fields,
|
||||||
|
r#"
|
||||||
|
struct Foo {
|
||||||
|
foo: u8,
|
||||||
|
bar: String,
|
||||||
|
baz: i128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self <|>{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
struct Foo {
|
||||||
|
foo: u8,
|
||||||
|
bar: String,
|
||||||
|
baz: i128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
<|>Self {
|
||||||
|
foo: (),
|
||||||
|
bar: (),
|
||||||
|
baz: (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue