aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/handlers/replace_if_let_with_match.rs6
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs3
-rw-r--r--crates/ra_assists/src/utils.rs38
-rw-r--r--crates/ra_fmt/src/lib.rs67
-rw-r--r--crates/ra_ide/src/join_lines.rs27
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 @@
1use ra_fmt::unwrap_trivial_block;
2use syntax::{ 1use syntax::{
3 ast::{ 2 ast::{
4 self, 3 self,
@@ -8,7 +7,10 @@ use syntax::{
8 AstNode, 7 AstNode,
9}; 8};
10 9
11use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists}; 10use 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 @@
1use ra_fmt::unwrap_trivial_block;
2use syntax::{ 1use 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
10use crate::{AssistContext, AssistId, AssistKind, Assists}; 9use 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;
4use std::{iter, ops}; 4use std::{iter, ops};
5 5
6use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; 6use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
7use itertools::Itertools;
7use ra_ide_db::RootDatabase; 8use ra_ide_db::RootDatabase;
8use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
9use syntax::{ 10use syntax::{
@@ -17,6 +18,43 @@ use crate::assist_config::SnippetCap;
17 18
18pub(crate) use insert_use::{find_insert_use_container, insert_use_statement}; 19pub(crate) use insert_use::{find_insert_use_container, insert_use_statement};
19 20
21pub(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
27pub 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)]
21pub(crate) enum Cursor<'a> { 59pub(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
3use std::iter::successors; 3use std::iter::successors;
4 4
5use itertools::Itertools;
6use syntax::{ 5use 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> {
29fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { 26fn 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
33pub 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
39pub 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
70pub 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 @@
1use itertools::Itertools; 1use itertools::Itertools;
2use ra_fmt::{compute_ws, extract_trivial_expression}; 2use ra_assists::utils::extract_trivial_expression;
3use syntax::{ 3use 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};
10use text_edit::{TextEdit, TextEditBuilder}; 10use 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
171fn 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)]
172mod tests { 195mod tests {
173 use syntax::SourceFile; 196 use syntax::SourceFile;