diff options
Diffstat (limited to 'crates/ra_assists/src/handlers/add_function.rs')
-rw-r--r-- | crates/ra_assists/src/handlers/add_function.rs | 44 |
1 files changed, 19 insertions, 25 deletions
diff --git a/crates/ra_assists/src/handlers/add_function.rs b/crates/ra_assists/src/handlers/add_function.rs index 6c7456579..278079665 100644 --- a/crates/ra_assists/src/handlers/add_function.rs +++ b/crates/ra_assists/src/handlers/add_function.rs | |||
@@ -3,9 +3,10 @@ use ra_syntax::{ | |||
3 | SyntaxKind, SyntaxNode, TextSize, | 3 | SyntaxKind, SyntaxNode, TextSize, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use crate::{Assist, AssistCtx, AssistFile, AssistId}; | 6 | use crate::{Assist, AssistCtx, AssistId}; |
7 | use ast::{edit::IndentLevel, ArgListOwner, ModuleItemOwner}; | 7 | use ast::{edit::IndentLevel, ArgListOwner, ModuleItemOwner}; |
8 | use hir::HirDisplay; | 8 | use hir::HirDisplay; |
9 | use ra_db::FileId; | ||
9 | use rustc_hash::{FxHashMap, FxHashSet}; | 10 | use rustc_hash::{FxHashMap, FxHashSet}; |
10 | 11 | ||
11 | // Assist: add_function | 12 | // Assist: add_function |
@@ -57,14 +58,12 @@ pub(crate) fn add_function(ctx: AssistCtx) -> Option<Assist> { | |||
57 | 58 | ||
58 | let function_builder = FunctionBuilder::from_call(&ctx, &call, &path, target_module)?; | 59 | let function_builder = FunctionBuilder::from_call(&ctx, &call, &path, target_module)?; |
59 | 60 | ||
60 | ctx.add_assist(AssistId("add_function"), "Add function", |edit| { | 61 | let target = call.syntax().text_range(); |
61 | edit.target(call.syntax().text_range()); | 62 | ctx.add_assist(AssistId("add_function"), "Add function", target, |edit| { |
62 | 63 | let function_template = function_builder.render(); | |
63 | if let Some(function_template) = function_builder.render() { | 64 | edit.set_file(function_template.file); |
64 | edit.set_file(function_template.file); | 65 | edit.set_cursor(function_template.cursor_offset); |
65 | edit.set_cursor(function_template.cursor_offset); | 66 | edit.insert(function_template.insert_offset, function_template.fn_def.to_string()); |
66 | edit.insert(function_template.insert_offset, function_template.fn_def.to_string()); | ||
67 | } | ||
68 | }) | 67 | }) |
69 | } | 68 | } |
70 | 69 | ||
@@ -72,7 +71,7 @@ struct FunctionTemplate { | |||
72 | insert_offset: TextSize, | 71 | insert_offset: TextSize, |
73 | cursor_offset: TextSize, | 72 | cursor_offset: TextSize, |
74 | fn_def: ast::SourceFile, | 73 | fn_def: ast::SourceFile, |
75 | file: AssistFile, | 74 | file: FileId, |
76 | } | 75 | } |
77 | 76 | ||
78 | struct FunctionBuilder { | 77 | struct FunctionBuilder { |
@@ -80,7 +79,7 @@ struct FunctionBuilder { | |||
80 | fn_name: ast::Name, | 79 | fn_name: ast::Name, |
81 | type_params: Option<ast::TypeParamList>, | 80 | type_params: Option<ast::TypeParamList>, |
82 | params: ast::ParamList, | 81 | params: ast::ParamList, |
83 | file: AssistFile, | 82 | file: FileId, |
84 | needs_pub: bool, | 83 | needs_pub: bool, |
85 | } | 84 | } |
86 | 85 | ||
@@ -94,7 +93,7 @@ impl FunctionBuilder { | |||
94 | target_module: Option<hir::InFile<hir::ModuleSource>>, | 93 | target_module: Option<hir::InFile<hir::ModuleSource>>, |
95 | ) -> Option<Self> { | 94 | ) -> Option<Self> { |
96 | let needs_pub = target_module.is_some(); | 95 | let needs_pub = target_module.is_some(); |
97 | let mut file = AssistFile::default(); | 96 | let mut file = ctx.frange.file_id; |
98 | let target = if let Some(target_module) = target_module { | 97 | let target = if let Some(target_module) = target_module { |
99 | let (in_file, target) = next_space_for_fn_in_module(ctx.sema.db, target_module)?; | 98 | let (in_file, target) = next_space_for_fn_in_module(ctx.sema.db, target_module)?; |
100 | file = in_file; | 99 | file = in_file; |
@@ -107,7 +106,7 @@ impl FunctionBuilder { | |||
107 | Some(Self { target, fn_name, type_params, params, file, needs_pub }) | 106 | Some(Self { target, fn_name, type_params, params, file, needs_pub }) |
108 | } | 107 | } |
109 | 108 | ||
110 | fn render(self) -> Option<FunctionTemplate> { | 109 | fn render(self) -> FunctionTemplate { |
111 | let placeholder_expr = ast::make::expr_todo(); | 110 | let placeholder_expr = ast::make::expr_todo(); |
112 | let fn_body = ast::make::block_expr(vec![], Some(placeholder_expr)); | 111 | let fn_body = ast::make::block_expr(vec![], Some(placeholder_expr)); |
113 | let mut fn_def = ast::make::fn_def(self.fn_name, self.type_params, self.params, fn_body); | 112 | let mut fn_def = ast::make::fn_def(self.fn_name, self.type_params, self.params, fn_body); |
@@ -133,15 +132,11 @@ impl FunctionBuilder { | |||
133 | } | 132 | } |
134 | }; | 133 | }; |
135 | 134 | ||
136 | let cursor_offset_from_fn_start = fn_def | 135 | let placeholder_expr = |
137 | .syntax() | 136 | fn_def.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); |
138 | .descendants() | 137 | let cursor_offset_from_fn_start = placeholder_expr.syntax().text_range().start(); |
139 | .find_map(ast::MacroCall::cast)? | ||
140 | .syntax() | ||
141 | .text_range() | ||
142 | .start(); | ||
143 | let cursor_offset = insert_offset + cursor_offset_from_fn_start; | 138 | let cursor_offset = insert_offset + cursor_offset_from_fn_start; |
144 | Some(FunctionTemplate { insert_offset, cursor_offset, fn_def, file: self.file }) | 139 | FunctionTemplate { insert_offset, cursor_offset, fn_def, file: self.file } |
145 | } | 140 | } |
146 | } | 141 | } |
147 | 142 | ||
@@ -259,9 +254,8 @@ fn next_space_for_fn_after_call_site(expr: &ast::CallExpr) -> Option<GeneratedFu | |||
259 | fn next_space_for_fn_in_module( | 254 | fn next_space_for_fn_in_module( |
260 | db: &dyn hir::db::AstDatabase, | 255 | db: &dyn hir::db::AstDatabase, |
261 | module: hir::InFile<hir::ModuleSource>, | 256 | module: hir::InFile<hir::ModuleSource>, |
262 | ) -> Option<(AssistFile, GeneratedFunctionTarget)> { | 257 | ) -> Option<(FileId, GeneratedFunctionTarget)> { |
263 | let file = module.file_id.original_file(db); | 258 | let file = module.file_id.original_file(db); |
264 | let assist_file = AssistFile::TargetFile(file); | ||
265 | let assist_item = match module.value { | 259 | let assist_item = match module.value { |
266 | hir::ModuleSource::SourceFile(it) => { | 260 | hir::ModuleSource::SourceFile(it) => { |
267 | if let Some(last_item) = it.items().last() { | 261 | if let Some(last_item) = it.items().last() { |
@@ -278,12 +272,12 @@ fn next_space_for_fn_in_module( | |||
278 | } | 272 | } |
279 | } | 273 | } |
280 | }; | 274 | }; |
281 | Some((assist_file, assist_item)) | 275 | Some((file, assist_item)) |
282 | } | 276 | } |
283 | 277 | ||
284 | #[cfg(test)] | 278 | #[cfg(test)] |
285 | mod tests { | 279 | mod tests { |
286 | use crate::helpers::{check_assist, check_assist_not_applicable}; | 280 | use crate::tests::{check_assist, check_assist_not_applicable}; |
287 | 281 | ||
288 | use super::*; | 282 | use super::*; |
289 | 283 | ||