Skip to content

Commit 987ab1f

Browse files
committed
implement feedback from review
1 parent 68ffe91 commit 987ab1f

File tree

2 files changed

+54
-20
lines changed

2 files changed

+54
-20
lines changed

crates/ide_assists/src/handlers/generate_delegate_methods.rs

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use hir::{self, HasCrate, HasSource, HirDisplay};
22
use syntax::ast::{self, make, AstNode, HasGenericParams, HasName, HasVisibility};
33

44
use crate::{
5-
utils::{find_struct_impl, render_snippet, Cursor},
5+
utils::{convert_param_list_to_arg_list, find_struct_impl, render_snippet, Cursor},
66
AssistContext, AssistId, AssistKind, Assists, GroupLabel,
77
};
88
use syntax::ast::edit::AstNodeEdit;
@@ -43,8 +43,6 @@ use syntax::ast::edit::AstNodeEdit;
4343
// }
4444
// ```
4545
pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
46-
let cap = ctx.config.snippet_cap?;
47-
4846
let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
4947
let strukt_name = strukt.name()?;
5048

@@ -57,8 +55,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
5755
None => {
5856
let field = ctx.find_node_at_offset::<ast::TupleField>()?;
5957
let field_list = ctx.find_node_at_offset::<ast::TupleFieldList>()?;
60-
let field_list_index =
61-
field_list.syntax().children().into_iter().position(|s| &s == field.syntax())?;
58+
let field_list_index = field_list.fields().position(|it| it == field)?;
6259
let field_ty = field.ty()?;
6360
(format!("{}", field_list_index), field_ty)
6461
}
@@ -73,16 +70,14 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
7370
methods.push(f)
7471
}
7572
}
76-
Some(())
73+
Option::<()>::None
7774
});
7875

7976
let target = field_ty.syntax().text_range();
8077
for method in methods {
81-
let impl_def = find_struct_impl(
82-
ctx,
83-
&ast::Adt::Struct(strukt.clone()),
84-
&method.name(ctx.db()).to_string(),
85-
)?;
78+
let adt = ast::Adt::Struct(strukt.clone());
79+
let name = method.name(ctx.db()).to_string();
80+
let impl_def = find_struct_impl(ctx, &adt, &name).flatten();
8681
acc.add_group(
8782
&GroupLabel("Generate delegate methods…".to_owned()),
8883
AssistId("generate_delegate_methods", AssistKind::Generate),
@@ -99,15 +94,22 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
9994
let name = make::name(&method.name(ctx.db()).to_string());
10095
let params =
10196
method_source.param_list().unwrap_or_else(|| make::param_list(None, []));
97+
let type_params = method_source.generic_param_list();
98+
let arg_list = match method_source.param_list() {
99+
Some(list) => convert_param_list_to_arg_list(list),
100+
None => make::arg_list([]),
101+
};
102102
let tail_expr = make::expr_method_call(
103103
make::ext::field_from_idents(["self", &field_name]).unwrap(), // This unwrap is ok because we have at least 1 arg in the list
104104
make::name_ref(&method_name.to_string()),
105-
make::arg_list([]),
105+
arg_list,
106106
);
107-
let type_params = method_source.generic_param_list();
108107
let body = make::block_expr([], Some(tail_expr));
109108
let ret_type = method.ret_type(ctx.db());
110109
let ret_type = if ret_type.is_unknown() {
110+
// FIXME: we currently can't resolve certain generics, and
111+
// are returning placeholders instead. We should fix our
112+
// type resolution here, so we return fewer placeholders.
111113
Some(make::ret_type(make::ty_placeholder()))
112114
} else {
113115
let ret_type = &ret_type.display(ctx.db()).to_string();
@@ -133,8 +135,15 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
133135
assoc_items.add_item(f.clone().into());
134136

135137
// Update the impl block.
136-
let snippet = render_snippet(cap, impl_def.syntax(), cursor);
137-
builder.replace_snippet(cap, old_range, snippet);
138+
match ctx.config.snippet_cap {
139+
Some(cap) => {
140+
let snippet = render_snippet(cap, impl_def.syntax(), cursor);
141+
builder.replace_snippet(cap, old_range, snippet);
142+
}
143+
None => {
144+
builder.replace(old_range, impl_def.syntax().to_string());
145+
}
146+
}
138147
}
139148
None => {
140149
// Attach the function to the impl block
@@ -147,10 +156,19 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext)
147156
assoc_items.add_item(f.clone().into());
148157

149158
// Insert the impl block.
150-
let offset = strukt.syntax().text_range().end();
151-
let snippet = render_snippet(cap, impl_def.syntax(), cursor);
152-
let snippet = format!("\n\n{}", snippet);
153-
builder.insert_snippet(cap, offset, snippet);
159+
match ctx.config.snippet_cap {
160+
Some(cap) => {
161+
let offset = strukt.syntax().text_range().end();
162+
let snippet = render_snippet(cap, impl_def.syntax(), cursor);
163+
let snippet = format!("\n\n{}", snippet);
164+
builder.insert_snippet(cap, offset, snippet);
165+
}
166+
None => {
167+
let offset = strukt.syntax().text_range().end();
168+
let snippet = format!("\n\n{}", impl_def.syntax().to_string());
169+
builder.insert(offset, snippet);
170+
}
171+
}
154172
}
155173
}
156174
},
@@ -297,7 +315,7 @@ struct Person<T> {
297315
298316
impl<T> Person<T> {
299317
$0pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> _ {
300-
self.age.age()
318+
self.age.age(ty, arg)
301319
}
302320
}"#,
303321
);

crates/ide_assists/src/utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,3 +525,19 @@ pub(crate) fn trimmed_text_range(source_file: &SourceFile, initial_range: TextRa
525525
}
526526
trimmed_range
527527
}
528+
529+
/// Convert a list of function params to a list of arguments that can be passed
530+
/// into a function call.
531+
pub(crate) fn convert_param_list_to_arg_list(list: ast::ParamList) -> ast::ArgList {
532+
let mut args = vec![];
533+
for param in list.params() {
534+
if let Some(ast::Pat::IdentPat(pat)) = param.pat() {
535+
if let Some(name) = pat.name() {
536+
let name = name.to_string();
537+
let expr = make::expr_path(make::ext::ident_path(&name));
538+
args.push(expr);
539+
}
540+
}
541+
}
542+
make::arg_list(args)
543+
}

0 commit comments

Comments
 (0)