diff options
-rw-r--r-- | crates/ra_assists/src/assist_context.rs | 17 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/change_return_type_to_result.rs | 73 | ||||
-rw-r--r-- | crates/ra_fmt/src/lib.rs | 5 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 7 |
4 files changed, 48 insertions, 54 deletions
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs index 217f692a4..368d48a71 100644 --- a/crates/ra_assists/src/assist_context.rs +++ b/crates/ra_assists/src/assist_context.rs | |||
@@ -5,14 +5,13 @@ use std::mem; | |||
5 | use algo::find_covering_element; | 5 | use algo::find_covering_element; |
6 | use hir::Semantics; | 6 | use hir::Semantics; |
7 | use ra_db::{FileId, FileRange}; | 7 | use ra_db::{FileId, FileRange}; |
8 | use ra_fmt::{leading_indent, reindent}; | ||
9 | use ra_ide_db::{ | 8 | use ra_ide_db::{ |
10 | source_change::{SourceChange, SourceFileEdit}, | 9 | source_change::{SourceChange, SourceFileEdit}, |
11 | RootDatabase, | 10 | RootDatabase, |
12 | }; | 11 | }; |
13 | use syntax::{ | 12 | use syntax::{ |
14 | algo::{self, find_node_at_offset, SyntaxRewriter}, | 13 | algo::{self, find_node_at_offset, SyntaxRewriter}, |
15 | AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize, | 14 | AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange, TextSize, |
16 | TokenAtOffset, | 15 | TokenAtOffset, |
17 | }; | 16 | }; |
18 | use text_edit::{TextEdit, TextEditBuilder}; | 17 | use text_edit::{TextEdit, TextEditBuilder}; |
@@ -269,20 +268,6 @@ impl AssistBuilder { | |||
269 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { | 268 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { |
270 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) | 269 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) |
271 | } | 270 | } |
272 | /// Replaces specified `node` of text with a given string, reindenting the | ||
273 | /// string to maintain `node`'s existing indent. | ||
274 | // FIXME: remove in favor of syntax::edit::IndentLevel::increase_indent | ||
275 | pub(crate) fn replace_node_and_indent( | ||
276 | &mut self, | ||
277 | node: &SyntaxNode, | ||
278 | replace_with: impl Into<String>, | ||
279 | ) { | ||
280 | let mut replace_with = replace_with.into(); | ||
281 | if let Some(indent) = leading_indent(node) { | ||
282 | replace_with = reindent(&replace_with, &indent) | ||
283 | } | ||
284 | self.replace(node.text_range(), replace_with) | ||
285 | } | ||
286 | pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) { | 271 | pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) { |
287 | let node = rewriter.rewrite_root().unwrap(); | 272 | let node = rewriter.rewrite_root().unwrap(); |
288 | let new = rewriter.rewrite(&node); | 273 | let new = rewriter.rewrite(&node); |
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index d5a68a24c..be480943c 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs | |||
@@ -1,10 +1,12 @@ | |||
1 | use std::iter; | ||
2 | |||
1 | use syntax::{ | 3 | use syntax::{ |
2 | ast::{self, BlockExpr, Expr, LoopBodyOwner}, | 4 | ast::{self, make, BlockExpr, Expr, LoopBodyOwner}, |
3 | AstNode, SyntaxNode, | 5 | AstNode, SyntaxNode, |
4 | }; | 6 | }; |
7 | use test_utils::mark; | ||
5 | 8 | ||
6 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 9 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
7 | use test_utils::mark; | ||
8 | 10 | ||
9 | // Assist: change_return_type_to_result | 11 | // Assist: change_return_type_to_result |
10 | // | 12 | // |
@@ -44,7 +46,13 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex | |||
44 | tail_return_expr_collector.collect_tail_exprs(block_expr); | 46 | tail_return_expr_collector.collect_tail_exprs(block_expr); |
45 | 47 | ||
46 | for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { | 48 | for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { |
47 | builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); | 49 | let ok_wrapped = make::expr_call( |
50 | make::expr_path(make::path_unqualified(make::path_segment(make::name_ref( | ||
51 | "Ok", | ||
52 | )))), | ||
53 | make::arg_list(iter::once(ret_expr_arg.clone())), | ||
54 | ); | ||
55 | builder.replace_ast(ret_expr_arg, ok_wrapped); | ||
48 | } | 56 | } |
49 | 57 | ||
50 | match ctx.config.snippet_cap { | 58 | match ctx.config.snippet_cap { |
@@ -60,7 +68,7 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex | |||
60 | } | 68 | } |
61 | 69 | ||
62 | struct TailReturnCollector { | 70 | struct TailReturnCollector { |
63 | exprs_to_wrap: Vec<SyntaxNode>, | 71 | exprs_to_wrap: Vec<ast::Expr>, |
64 | } | 72 | } |
65 | 73 | ||
66 | impl TailReturnCollector { | 74 | impl TailReturnCollector { |
@@ -86,7 +94,8 @@ impl TailReturnCollector { | |||
86 | if let Some(last_exprs) = get_tail_expr_from_block(&expr) { | 94 | if let Some(last_exprs) = get_tail_expr_from_block(&expr) { |
87 | for last_expr in last_exprs { | 95 | for last_expr in last_exprs { |
88 | let last_expr = match last_expr { | 96 | let last_expr = match last_expr { |
89 | NodeType::Node(expr) | NodeType::Leaf(expr) => expr, | 97 | NodeType::Node(expr) => expr, |
98 | NodeType::Leaf(expr) => expr.syntax().clone(), | ||
90 | }; | 99 | }; |
91 | 100 | ||
92 | if let Some(last_expr) = Expr::cast(last_expr.clone()) { | 101 | if let Some(last_expr) = Expr::cast(last_expr.clone()) { |
@@ -113,12 +122,12 @@ impl TailReturnCollector { | |||
113 | } | 122 | } |
114 | Expr::ReturnExpr(ret_expr) => { | 123 | Expr::ReturnExpr(ret_expr) => { |
115 | if let Some(ret_expr_arg) = &ret_expr.expr() { | 124 | if let Some(ret_expr_arg) = &ret_expr.expr() { |
116 | self.exprs_to_wrap.push(ret_expr_arg.syntax().clone()); | 125 | self.exprs_to_wrap.push(ret_expr_arg.clone()); |
117 | } | 126 | } |
118 | } | 127 | } |
119 | Expr::BreakExpr(break_expr) if collect_break => { | 128 | Expr::BreakExpr(break_expr) if collect_break => { |
120 | if let Some(break_expr_arg) = &break_expr.expr() { | 129 | if let Some(break_expr_arg) = &break_expr.expr() { |
121 | self.exprs_to_wrap.push(break_expr_arg.syntax().clone()); | 130 | self.exprs_to_wrap.push(break_expr_arg.clone()); |
122 | } | 131 | } |
123 | } | 132 | } |
124 | Expr::IfExpr(if_expr) => { | 133 | Expr::IfExpr(if_expr) => { |
@@ -166,14 +175,11 @@ impl TailReturnCollector { | |||
166 | NodeType::Leaf(expr) => { | 175 | NodeType::Leaf(expr) => { |
167 | self.exprs_to_wrap.push(expr.clone()); | 176 | self.exprs_to_wrap.push(expr.clone()); |
168 | } | 177 | } |
169 | NodeType::Node(expr) => match &Expr::cast(expr.clone()) { | 178 | NodeType::Node(expr) => { |
170 | Some(last_expr) => { | 179 | if let Some(last_expr) = Expr::cast(expr.clone()) { |
171 | self.fetch_tail_exprs(last_expr); | 180 | self.fetch_tail_exprs(&last_expr); |
172 | } | ||
173 | None => { | ||
174 | self.exprs_to_wrap.push(expr.clone()); | ||
175 | } | 181 | } |
176 | }, | 182 | } |
177 | } | 183 | } |
178 | } | 184 | } |
179 | } | 185 | } |
@@ -182,7 +188,7 @@ impl TailReturnCollector { | |||
182 | 188 | ||
183 | #[derive(Debug)] | 189 | #[derive(Debug)] |
184 | enum NodeType { | 190 | enum NodeType { |
185 | Leaf(SyntaxNode), | 191 | Leaf(ast::Expr), |
186 | Node(SyntaxNode), | 192 | Node(SyntaxNode), |
187 | } | 193 | } |
188 | 194 | ||
@@ -233,25 +239,26 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> { | |||
233 | 239 | ||
234 | Some(arms) | 240 | Some(arms) |
235 | } | 241 | } |
236 | Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e.syntax().clone())]), | 242 | Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e)]), |
237 | Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]), | 243 | Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]), |
238 | Expr::CallExpr(call_expr) => Some(vec![NodeType::Leaf(call_expr.syntax().clone())]), | 244 | |
239 | Expr::Literal(lit_expr) => Some(vec![NodeType::Leaf(lit_expr.syntax().clone())]), | 245 | Expr::CallExpr(_) |
240 | Expr::TupleExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 246 | | Expr::Literal(_) |
241 | Expr::ArrayExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 247 | | Expr::TupleExpr(_) |
242 | Expr::ParenExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 248 | | Expr::ArrayExpr(_) |
243 | Expr::PathExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 249 | | Expr::ParenExpr(_) |
244 | Expr::RecordExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 250 | | Expr::PathExpr(_) |
245 | Expr::IndexExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 251 | | Expr::RecordExpr(_) |
246 | Expr::MethodCallExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 252 | | Expr::IndexExpr(_) |
247 | Expr::AwaitExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 253 | | Expr::MethodCallExpr(_) |
248 | Expr::CastExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 254 | | Expr::AwaitExpr(_) |
249 | Expr::RefExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 255 | | Expr::CastExpr(_) |
250 | Expr::PrefixExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 256 | | Expr::RefExpr(_) |
251 | Expr::RangeExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 257 | | Expr::PrefixExpr(_) |
252 | Expr::BinExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 258 | | Expr::RangeExpr(_) |
253 | Expr::MacroCall(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 259 | | Expr::BinExpr(_) |
254 | Expr::BoxExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), | 260 | | Expr::MacroCall(_) |
261 | | Expr::BoxExpr(_) => Some(vec![NodeType::Leaf(expr.clone())]), | ||
255 | _ => None, | 262 | _ => None, |
256 | } | 263 | } |
257 | } | 264 | } |
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index d0bf0593f..397a3c3ae 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs | |||
@@ -10,11 +10,6 @@ use syntax::{ | |||
10 | SyntaxNode, SyntaxToken, T, | 10 | SyntaxNode, SyntaxToken, T, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | pub fn reindent(text: &str, indent: &str) -> String { | ||
14 | let indent = format!("\n{}", indent); | ||
15 | text.lines().intersperse(&indent).collect() | ||
16 | } | ||
17 | |||
18 | /// If the node is on the beginning of the line, calculate indent. | 13 | /// If the node is on the beginning of the line, calculate indent. |
19 | pub fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> { | 14 | pub fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> { |
20 | for token in prev_tokens(node.first_token()?) { | 15 | for token in prev_tokens(node.first_token()?) { |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 3009faed7..d20c085aa 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -134,6 +134,9 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr { | |||
134 | let token = token(op); | 134 | let token = token(op); |
135 | expr_from_text(&format!("{}{}", token, expr)) | 135 | expr_from_text(&format!("{}{}", token, expr)) |
136 | } | 136 | } |
137 | pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr { | ||
138 | expr_from_text(&format!("{}{}", f, arg_list)) | ||
139 | } | ||
137 | fn expr_from_text(text: &str) -> ast::Expr { | 140 | fn expr_from_text(text: &str) -> ast::Expr { |
138 | ast_from_text(&format!("const C: () = {};", text)) | 141 | ast_from_text(&format!("const C: () = {};", text)) |
139 | } | 142 | } |
@@ -151,6 +154,10 @@ pub fn condition(expr: ast::Expr, pattern: Option<ast::Pat>) -> ast::Condition { | |||
151 | } | 154 | } |
152 | } | 155 | } |
153 | 156 | ||
157 | pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList { | ||
158 | ast_from_text(&format!("fn main() {{ ()({}) }}", args.into_iter().format(", "))) | ||
159 | } | ||
160 | |||
154 | pub fn ident_pat(name: ast::Name) -> ast::IdentPat { | 161 | pub fn ident_pat(name: ast::Name) -> ast::IdentPat { |
155 | return from_text(name.text()); | 162 | return from_text(name.text()); |
156 | 163 | ||