Fix a bunch of false-positives in join-lines

This commit is contained in:
Aleksey Kladov 2020-04-30 21:36:31 +02:00
parent 23c889694e
commit 15cfa9a808
5 changed files with 83 additions and 14 deletions

View file

@ -57,18 +57,17 @@ pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
return None; return None;
} }
return Some(expr); return Some(expr);
} else { }
// Unwrap `{ continue; }` // Unwrap `{ continue; }`
let (stmt,) = block.statements().next_tuple()?; let (stmt,) = block.statements().next_tuple()?;
if let ast::Stmt::ExprStmt(expr_stmt) = stmt { if let ast::Stmt::ExprStmt(expr_stmt) = stmt {
if has_anything_else(expr_stmt.syntax()) { if has_anything_else(expr_stmt.syntax()) {
return None; return None;
} }
let expr = expr_stmt.expr()?; let expr = expr_stmt.expr()?;
match expr.syntax().kind() { match expr.syntax().kind() {
CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr), CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr),
_ => (), _ => (),
}
} }
} }
None None

View file

@ -131,6 +131,9 @@ fn has_comma_after(node: &SyntaxNode) -> bool {
fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> {
let block = ast::Block::cast(token.parent())?; let block = ast::Block::cast(token.parent())?;
let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
if !block_expr.is_standalone() {
return None;
}
let expr = extract_trivial_expression(&block_expr)?; let expr = extract_trivial_expression(&block_expr)?;
let block_range = block_expr.syntax().text_range(); let block_range = block_expr.syntax().text_range();
@ -662,4 +665,67 @@ fn main() {
", ",
) )
} }
#[test]
fn join_lines_mandatory_blocks_block() {
check_join_lines(
r"
<|>fn foo() {
92
}
",
r"
<|>fn foo() { 92
}
",
);
check_join_lines(
r"
fn foo() {
<|>if true {
92
}
}
",
r"
fn foo() {
<|>if true { 92
}
}
",
);
check_join_lines(
r"
fn foo() {
<|>loop {
92
}
}
",
r"
fn foo() {
<|>loop { 92
}
}
",
);
check_join_lines(
r"
fn foo() {
<|>unsafe {
92
}
}
",
r"
fn foo() {
<|>unsafe { 92
}
}
",
);
}
} }

View file

@ -368,12 +368,15 @@ impl ast::BlockExpr {
/// const FOO: () = { stand_alone }; /// const FOO: () = { stand_alone };
/// ``` /// ```
pub fn is_standalone(&self) -> bool { pub fn is_standalone(&self) -> bool {
if self.unsafe_token().is_some() || self.async_token().is_some() {
return false;
}
let kind = match self.syntax().parent() { let kind = match self.syntax().parent() {
None => return true, None => return true,
Some(it) => it.kind(), Some(it) => it.kind(),
}; };
match kind { match kind {
FN_DEF | MATCH_ARM | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false, FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false,
_ => true, _ => true,
} }
} }

View file

@ -554,6 +554,7 @@ impl ast::AttrsOwner for BlockExpr {}
impl BlockExpr { impl BlockExpr {
pub fn label(&self) -> Option<Label> { support::child(&self.syntax) } pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
pub fn block(&self) -> Option<Block> { support::child(&self.syntax) } pub fn block(&self) -> Option<Block> { support::child(&self.syntax) }
} }

View file

@ -451,7 +451,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] } struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr } struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
struct Label { T![lifetime] } struct Label { T![lifetime] }
struct BlockExpr: AttrsOwner { Label, T![unsafe], Block } struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block }
struct ReturnExpr: AttrsOwner { Expr } struct ReturnExpr: AttrsOwner { Expr }
struct CallExpr: ArgListOwner { Expr } struct CallExpr: ArgListOwner { Expr }
struct MethodCallExpr: AttrsOwner, ArgListOwner { struct MethodCallExpr: AttrsOwner, ArgListOwner {