diff options
-rw-r--r-- | crates/ra_assists/src/handlers/replace_if_let_with_match.rs | 6 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/unwrap_block.rs | 3 | ||||
-rw-r--r-- | crates/ra_assists/src/utils.rs | 38 | ||||
-rw-r--r-- | crates/ra_fmt/src/lib.rs | 67 | ||||
-rw-r--r-- | crates/ra_ide/src/join_lines.rs | 27 |
5 files changed, 70 insertions, 71 deletions
diff --git a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs index 2442f049b..79097621e 100644 --- a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use ra_fmt::unwrap_trivial_block; | ||
2 | use syntax::{ | 1 | use syntax::{ |
3 | ast::{ | 2 | ast::{ |
4 | self, | 3 | self, |
@@ -8,7 +7,10 @@ use syntax::{ | |||
8 | AstNode, | 7 | AstNode, |
9 | }; | 8 | }; |
10 | 9 | ||
11 | use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists}; | 10 | use crate::{ |
11 | utils::{unwrap_trivial_block, TryEnum}, | ||
12 | AssistContext, AssistId, AssistKind, Assists, | ||
13 | }; | ||
12 | 14 | ||
13 | // Assist: replace_if_let_with_match | 15 | // Assist: replace_if_let_with_match |
14 | // | 16 | // |
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs index 2879090b8..3851aeb3e 100644 --- a/crates/ra_assists/src/handlers/unwrap_block.rs +++ b/crates/ra_assists/src/handlers/unwrap_block.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use ra_fmt::unwrap_trivial_block; | ||
2 | use syntax::{ | 1 | use syntax::{ |
3 | ast::{ | 2 | ast::{ |
4 | self, | 3 | self, |
@@ -7,7 +6,7 @@ use syntax::{ | |||
7 | AstNode, TextRange, T, | 6 | AstNode, TextRange, T, |
8 | }; | 7 | }; |
9 | 8 | ||
10 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 9 | use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists}; |
11 | 10 | ||
12 | // Assist: unwrap_block | 11 | // Assist: unwrap_block |
13 | // | 12 | // |
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs index 6d85661c4..a20453dd8 100644 --- a/crates/ra_assists/src/utils.rs +++ b/crates/ra_assists/src/utils.rs | |||
@@ -4,6 +4,7 @@ pub(crate) mod insert_use; | |||
4 | use std::{iter, ops}; | 4 | use std::{iter, ops}; |
5 | 5 | ||
6 | use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; | 6 | use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; |
7 | use itertools::Itertools; | ||
7 | use ra_ide_db::RootDatabase; | 8 | use ra_ide_db::RootDatabase; |
8 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
9 | use syntax::{ | 10 | use syntax::{ |
@@ -17,6 +18,43 @@ use crate::assist_config::SnippetCap; | |||
17 | 18 | ||
18 | pub(crate) use insert_use::{find_insert_use_container, insert_use_statement}; | 19 | pub(crate) use insert_use::{find_insert_use_container, insert_use_statement}; |
19 | 20 | ||
21 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { | ||
22 | extract_trivial_expression(&block) | ||
23 | .filter(|expr| !expr.syntax().text().contains_char('\n')) | ||
24 | .unwrap_or_else(|| block.into()) | ||
25 | } | ||
26 | |||
27 | pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { | ||
28 | let has_anything_else = |thing: &SyntaxNode| -> bool { | ||
29 | let mut non_trivial_children = | ||
30 | block.syntax().children_with_tokens().filter(|it| match it.kind() { | ||
31 | WHITESPACE | T!['{'] | T!['}'] => false, | ||
32 | _ => it.as_node() != Some(thing), | ||
33 | }); | ||
34 | non_trivial_children.next().is_some() | ||
35 | }; | ||
36 | |||
37 | if let Some(expr) = block.expr() { | ||
38 | if has_anything_else(expr.syntax()) { | ||
39 | return None; | ||
40 | } | ||
41 | return Some(expr); | ||
42 | } | ||
43 | // Unwrap `{ continue; }` | ||
44 | let (stmt,) = block.statements().next_tuple()?; | ||
45 | if let ast::Stmt::ExprStmt(expr_stmt) = stmt { | ||
46 | if has_anything_else(expr_stmt.syntax()) { | ||
47 | return None; | ||
48 | } | ||
49 | let expr = expr_stmt.expr()?; | ||
50 | match expr.syntax().kind() { | ||
51 | CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr), | ||
52 | _ => (), | ||
53 | } | ||
54 | } | ||
55 | None | ||
56 | } | ||
57 | |||
20 | #[derive(Clone, Copy, Debug)] | 58 | #[derive(Clone, Copy, Debug)] |
21 | pub(crate) enum Cursor<'a> { | 59 | pub(crate) enum Cursor<'a> { |
22 | Replace(&'a SyntaxNode), | 60 | Replace(&'a SyntaxNode), |
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index 397a3c3ae..b92477f9e 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs | |||
@@ -2,12 +2,9 @@ | |||
2 | 2 | ||
3 | use std::iter::successors; | 3 | use std::iter::successors; |
4 | 4 | ||
5 | use itertools::Itertools; | ||
6 | use syntax::{ | 5 | use syntax::{ |
7 | ast::{self, AstNode, AstToken}, | 6 | ast::{self, AstToken}, |
8 | SmolStr, SyntaxKind, | 7 | SmolStr, SyntaxNode, SyntaxToken, |
9 | SyntaxKind::*, | ||
10 | SyntaxNode, SyntaxToken, T, | ||
11 | }; | 8 | }; |
12 | 9 | ||
13 | /// If the node is on the beginning of the line, calculate indent. | 10 | /// If the node is on the beginning of the line, calculate indent. |
@@ -29,63 +26,3 @@ pub fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> { | |||
29 | fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { | 26 | fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { |
30 | successors(token.prev_token(), |token| token.prev_token()) | 27 | successors(token.prev_token(), |token| token.prev_token()) |
31 | } | 28 | } |
32 | |||
33 | pub fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { | ||
34 | extract_trivial_expression(&block) | ||
35 | .filter(|expr| !expr.syntax().text().contains_char('\n')) | ||
36 | .unwrap_or_else(|| block.into()) | ||
37 | } | ||
38 | |||
39 | pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { | ||
40 | let has_anything_else = |thing: &SyntaxNode| -> bool { | ||
41 | let mut non_trivial_children = | ||
42 | block.syntax().children_with_tokens().filter(|it| match it.kind() { | ||
43 | WHITESPACE | T!['{'] | T!['}'] => false, | ||
44 | _ => it.as_node() != Some(thing), | ||
45 | }); | ||
46 | non_trivial_children.next().is_some() | ||
47 | }; | ||
48 | |||
49 | if let Some(expr) = block.expr() { | ||
50 | if has_anything_else(expr.syntax()) { | ||
51 | return None; | ||
52 | } | ||
53 | return Some(expr); | ||
54 | } | ||
55 | // Unwrap `{ continue; }` | ||
56 | let (stmt,) = block.statements().next_tuple()?; | ||
57 | if let ast::Stmt::ExprStmt(expr_stmt) = stmt { | ||
58 | if has_anything_else(expr_stmt.syntax()) { | ||
59 | return None; | ||
60 | } | ||
61 | let expr = expr_stmt.expr()?; | ||
62 | match expr.syntax().kind() { | ||
63 | CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr), | ||
64 | _ => (), | ||
65 | } | ||
66 | } | ||
67 | None | ||
68 | } | ||
69 | |||
70 | pub fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str { | ||
71 | match left { | ||
72 | T!['('] | T!['['] => return "", | ||
73 | T!['{'] => { | ||
74 | if let USE_TREE = right { | ||
75 | return ""; | ||
76 | } | ||
77 | } | ||
78 | _ => (), | ||
79 | } | ||
80 | match right { | ||
81 | T![')'] | T![']'] => return "", | ||
82 | T!['}'] => { | ||
83 | if let USE_TREE = left { | ||
84 | return ""; | ||
85 | } | ||
86 | } | ||
87 | T![.] => return "", | ||
88 | _ => (), | ||
89 | } | ||
90 | " " | ||
91 | } | ||
diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs index 35cec87f6..f5c310701 100644 --- a/crates/ra_ide/src/join_lines.rs +++ b/crates/ra_ide/src/join_lines.rs | |||
@@ -1,10 +1,10 @@ | |||
1 | use itertools::Itertools; | 1 | use itertools::Itertools; |
2 | use ra_fmt::{compute_ws, extract_trivial_expression}; | 2 | use ra_assists::utils::extract_trivial_expression; |
3 | use syntax::{ | 3 | use syntax::{ |
4 | algo::{find_covering_element, non_trivia_sibling}, | 4 | algo::{find_covering_element, non_trivia_sibling}, |
5 | ast::{self, AstNode, AstToken}, | 5 | ast::{self, AstNode, AstToken}, |
6 | Direction, NodeOrToken, SourceFile, | 6 | Direction, NodeOrToken, SourceFile, |
7 | SyntaxKind::{self, WHITESPACE}, | 7 | SyntaxKind::{self, USE_TREE, WHITESPACE}, |
8 | SyntaxNode, SyntaxToken, TextRange, TextSize, T, | 8 | SyntaxNode, SyntaxToken, TextRange, TextSize, T, |
9 | }; | 9 | }; |
10 | use text_edit::{TextEdit, TextEditBuilder}; | 10 | use text_edit::{TextEdit, TextEditBuilder}; |
@@ -168,6 +168,29 @@ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool { | |||
168 | matches!((left, right), (T![,], T![')']) | (T![,], T![']'])) | 168 | matches!((left, right), (T![,], T![')']) | (T![,], T![']'])) |
169 | } | 169 | } |
170 | 170 | ||
171 | fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str { | ||
172 | match left { | ||
173 | T!['('] | T!['['] => return "", | ||
174 | T!['{'] => { | ||
175 | if let USE_TREE = right { | ||
176 | return ""; | ||
177 | } | ||
178 | } | ||
179 | _ => (), | ||
180 | } | ||
181 | match right { | ||
182 | T![')'] | T![']'] => return "", | ||
183 | T!['}'] => { | ||
184 | if let USE_TREE = left { | ||
185 | return ""; | ||
186 | } | ||
187 | } | ||
188 | T![.] => return "", | ||
189 | _ => (), | ||
190 | } | ||
191 | " " | ||
192 | } | ||
193 | |||
171 | #[cfg(test)] | 194 | #[cfg(test)] |
172 | mod tests { | 195 | mod tests { |
173 | use syntax::SourceFile; | 196 | use syntax::SourceFile; |