Skip to content

Commit 50923ad

Browse files
committed
func gen: seperate generation form position(3)
1 parent 1ac9400 commit 50923ad

File tree

1 file changed

+85
-88
lines changed

1 file changed

+85
-88
lines changed

crates/ide_assists/src/handlers/generate_function.rs

Lines changed: 85 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use syntax::{
66
ast::{
77
self,
88
edit::{AstNodeEdit, IndentLevel},
9-
make, ArgListOwner, AstNode, ModuleItemOwner,
9+
make, ArgListOwner, AstNode, CallExpr, ModuleItemOwner,
1010
},
1111
SyntaxKind, SyntaxNode, TextRange, TextSize,
1212
};
@@ -85,10 +85,10 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
8585
None => None,
8686
};
8787

88-
let (function_builder, inserting_offset, file) =
89-
FunctionBuilder::from_call(ctx, &call, &path, target_module)?;
88+
let (target, file, insert_offset) = get_fn_target(ctx, &target_module, call.clone())?;
89+
let function_builder = FunctionBuilder::from_call(ctx, &call, &path, target_module, target)?;
9090
let target = call.syntax().text_range();
91-
add_func_to_accumulator(acc, ctx, target, function_builder, inserting_offset, file, None)
91+
add_func_to_accumulator(acc, ctx, target, function_builder, insert_offset, file, None)
9292
}
9393

9494
fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
@@ -109,24 +109,26 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
109109
ctx.sema.find_node_at_offset_with_macros(file.syntax(), range.range.start())?;
110110
let impl_ = find_struct_impl(ctx, &adt_source, fn_name.text().as_str())?;
111111

112-
let (function_builder, inserting_offset, file) = FunctionBuilder::from_method_call(
112+
let (target, insert_offset) = get_method_target(ctx, &target_module, &impl_)?;
113+
let function_builder =
114+
FunctionBuilder::from_method_call(ctx, &call, &fn_name, target_module, target)?;
115+
let text_range = call.syntax().text_range();
116+
let adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None };
117+
add_func_to_accumulator(
118+
acc,
113119
ctx,
114-
&call,
115-
&fn_name,
116-
&impl_,
120+
text_range,
121+
function_builder,
122+
insert_offset,
117123
range.file_id,
118-
target_module,
119-
current_module,
120-
)?;
121-
let target = call.syntax().text_range();
122-
let adt_name = if impl_.is_none() { Some(adt.name(ctx.sema.db)) } else { None };
123-
add_func_to_accumulator(acc, ctx, target, function_builder, inserting_offset, file, adt_name)
124+
adt_name,
125+
)
124126
}
125127

126128
fn add_func_to_accumulator(
127129
acc: &mut Assists,
128130
ctx: &AssistContext,
129-
target: TextRange,
131+
text_range: TextRange,
130132
function_builder: FunctionBuilder,
131133
insert_offset: TextSize,
132134
file: FileId,
@@ -135,7 +137,7 @@ fn add_func_to_accumulator(
135137
acc.add(
136138
AssistId("generate_function", AssistKind::Generate),
137139
format!("Generate `{}` method", function_builder.fn_name),
138-
target,
140+
text_range,
139141
|builder| {
140142
let function_template = function_builder.render();
141143
let mut func = function_template.to_string(ctx.config.snippet_cap);
@@ -194,7 +196,6 @@ struct FunctionBuilder {
194196
params: ast::ParamList,
195197
ret_type: Option<ast::RetType>,
196198
should_focus_return_type: bool,
197-
file: FileId,
198199
needs_pub: bool,
199200
is_async: bool,
200201
}
@@ -207,17 +208,8 @@ impl FunctionBuilder {
207208
call: &ast::CallExpr,
208209
path: &ast::Path,
209210
target_module: Option<hir::Module>,
210-
) -> Option<(Self, TextSize, FileId)> {
211-
let mut file = ctx.frange.file_id;
212-
let target = match &target_module {
213-
Some(target_module) => {
214-
let module_source = target_module.definition_source(ctx.db());
215-
let (in_file, target) = next_space_for_fn_in_module(ctx.sema.db, &module_source)?;
216-
file = in_file;
217-
target
218-
}
219-
None => next_space_for_fn_after_call_site(FuncExpr::Func(call.clone()))?,
220-
};
211+
target: GeneratedFunctionTarget,
212+
) -> Option<Self> {
221213
let needs_pub = target_module.is_some();
222214
let target_module = target_module.or_else(|| current_module(target.syntax(), ctx))?;
223215
let fn_name = fn_name(path)?;
@@ -229,51 +221,27 @@ impl FunctionBuilder {
229221
let (ret_type, should_focus_return_type) =
230222
make_return_type(ctx, &ast::Expr::CallExpr(call.clone()), target_module);
231223

232-
let insert_offset = match &target {
233-
GeneratedFunctionTarget::BehindItem(it) => it.text_range().end(),
234-
GeneratedFunctionTarget::InEmptyItemList(it) => {
235-
it.text_range().start() + TextSize::of('{')
236-
}
237-
};
238-
239-
Some((
240-
Self {
241-
target,
242-
fn_name,
243-
type_params,
244-
params,
245-
ret_type,
246-
should_focus_return_type,
247-
file,
248-
needs_pub,
249-
is_async,
250-
},
251-
insert_offset,
252-
file,
253-
))
224+
Some(Self {
225+
target,
226+
fn_name,
227+
type_params,
228+
params,
229+
ret_type,
230+
should_focus_return_type,
231+
needs_pub,
232+
is_async,
233+
})
254234
}
255235

256236
fn from_method_call(
257237
ctx: &AssistContext,
258238
call: &ast::MethodCallExpr,
259239
name: &ast::NameRef,
260-
impl_: &Option<ast::Impl>,
261-
file: FileId,
262240
target_module: Module,
263-
current_module: Module,
264-
) -> Option<(Self, TextSize, FileId)> {
265-
let target = match impl_ {
266-
Some(impl_) => next_space_for_fn_in_impl(&impl_)?,
267-
None => {
268-
next_space_for_fn_in_module(
269-
ctx.sema.db,
270-
&target_module.definition_source(ctx.sema.db),
271-
)?
272-
.1
273-
}
274-
};
275-
let needs_pub = !module_is_descendant(&current_module, &target_module, ctx);
276-
241+
target: GeneratedFunctionTarget,
242+
) -> Option<Self> {
243+
let needs_pub =
244+
!module_is_descendant(&current_module(call.syntax(), ctx)?, &target_module, ctx);
277245
let fn_name = make::name(&name.text());
278246
let (type_params, params) = fn_args(ctx, target_module, FuncExpr::Method(call.clone()))?;
279247

@@ -283,28 +251,16 @@ impl FunctionBuilder {
283251
let (ret_type, should_focus_return_type) =
284252
make_return_type(ctx, &ast::Expr::MethodCallExpr(call.clone()), target_module);
285253

286-
let insert_offset = match &target {
287-
GeneratedFunctionTarget::BehindItem(it) => it.text_range().end(),
288-
GeneratedFunctionTarget::InEmptyItemList(it) => {
289-
it.text_range().start() + TextSize::of('{')
290-
}
291-
};
292-
293-
Some((
294-
Self {
295-
target,
296-
fn_name,
297-
type_params,
298-
params,
299-
ret_type,
300-
should_focus_return_type,
301-
file,
302-
needs_pub,
303-
is_async,
304-
},
305-
insert_offset,
306-
file,
307-
))
254+
Some(Self {
255+
target,
256+
fn_name,
257+
type_params,
258+
params,
259+
ret_type,
260+
should_focus_return_type,
261+
needs_pub,
262+
is_async,
263+
})
308264
}
309265

310266
fn render(self) -> FunctionTemplate {
@@ -382,6 +338,47 @@ fn make_return_type(
382338
(ret_type, should_focus_return_type)
383339
}
384340

341+
fn get_fn_target(
342+
ctx: &AssistContext,
343+
target_module: &Option<Module>,
344+
call: CallExpr,
345+
) -> Option<(GeneratedFunctionTarget, FileId, TextSize)> {
346+
let mut file = ctx.frange.file_id;
347+
let target = match target_module {
348+
Some(target_module) => {
349+
let module_source = target_module.definition_source(ctx.db());
350+
let (in_file, target) = next_space_for_fn_in_module(ctx.sema.db, &module_source)?;
351+
file = in_file;
352+
target
353+
}
354+
None => next_space_for_fn_after_call_site(FuncExpr::Func(call.clone()))?,
355+
};
356+
Some((target.clone(), file, get_insert_offset(&target)))
357+
}
358+
359+
fn get_method_target(
360+
ctx: &AssistContext,
361+
target_module: &Module,
362+
impl_: &Option<ast::Impl>,
363+
) -> Option<(GeneratedFunctionTarget, TextSize)> {
364+
let target = match impl_ {
365+
Some(impl_) => next_space_for_fn_in_impl(&impl_)?,
366+
None => {
367+
next_space_for_fn_in_module(ctx.sema.db, &target_module.definition_source(ctx.sema.db))?
368+
.1
369+
}
370+
};
371+
Some((target.clone(), get_insert_offset(&target)))
372+
}
373+
374+
fn get_insert_offset(target: &GeneratedFunctionTarget) -> TextSize {
375+
match &target {
376+
GeneratedFunctionTarget::BehindItem(it) => it.text_range().end(),
377+
GeneratedFunctionTarget::InEmptyItemList(it) => it.text_range().start() + TextSize::of('{'),
378+
}
379+
}
380+
381+
#[derive(Clone)]
385382
enum GeneratedFunctionTarget {
386383
BehindItem(SyntaxNode),
387384
InEmptyItemList(SyntaxNode),

0 commit comments

Comments
 (0)