fix code duplication

This commit is contained in:
Aleksey Kladov 2019-01-10 18:32:02 +03:00
parent 3ca76c2039
commit a0c978cd0c
4 changed files with 55 additions and 68 deletions

View file

@ -1,9 +1,9 @@
use ra_syntax::{
AstNode, SyntaxKind::{L_CURLY, R_CURLY, WHITESPACE},
ast,
};
use ra_syntax::{AstNode, ast};
use crate::assists::{AssistCtx, Assist};
use crate::{
assists::{AssistCtx, Assist},
formatting::extract_trivial_expression,
};
pub fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> {
let if_expr: &ast::IfExpr = ctx.node_at_offset()?;
@ -39,26 +39,12 @@ fn build_match_expr(
}
fn format_arm(block: &ast::Block) -> String {
match extract_expression(block) {
match extract_trivial_expression(block) {
None => block.syntax().text().to_string(),
Some(e) => format!("{},", e.syntax().text()),
}
}
fn extract_expression(block: &ast::Block) -> Option<&ast::Expr> {
let expr = block.expr()?;
let non_trivial_children = block.syntax().children().filter(|it| {
!(it == &expr.syntax()
|| it.kind() == L_CURLY
|| it.kind() == R_CURLY
|| it.kind() == WHITESPACE)
});
if non_trivial_children.count() > 0 {
return None;
}
Some(expr)
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -0,0 +1,42 @@
use ra_syntax::{
ast, AstNode,
SyntaxNode, SyntaxKind::*,
};
pub(crate) fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> {
let expr = block.expr()?;
if expr.syntax().text().contains('\n') {
return None;
}
let non_trivial_children = block.syntax().children().filter(|it| match it.kind() {
WHITESPACE | L_CURLY | R_CURLY => false,
_ => it != &expr.syntax(),
});
if non_trivial_children.count() > 0 {
return None;
}
Some(expr)
}
pub(crate) fn compute_ws(left: &SyntaxNode, right: &SyntaxNode) -> &'static str {
match left.kind() {
L_PAREN | L_BRACK => return "",
L_CURLY => {
if let USE_TREE = right.kind() {
return "";
}
}
_ => (),
}
match right.kind() {
R_PAREN | R_BRACK => return "",
R_CURLY => {
if let USE_TREE = left.kind() {
return "";
}
}
DOT => return "",
_ => (),
}
" "
}

View file

@ -1,14 +1,15 @@
use std::mem;
use itertools::Itertools;
use ra_syntax::{
SourceFile, TextRange, TextUnit, AstNode, SyntaxNode,
SyntaxKind::{self, WHITESPACE, COMMA, L_CURLY, R_CURLY, L_PAREN, R_PAREN, L_BRACK, R_BRACK, USE_TREE, DOT},
SyntaxKind::{self, WHITESPACE, COMMA, R_CURLY, R_PAREN, R_BRACK},
algo::find_covering_node,
ast,
};
use crate::{LocalEdit, TextEditBuilder};
use crate::{
LocalEdit, TextEditBuilder,
formatting::{compute_ws, extract_trivial_expression},
};
pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit {
let range = if range.is_empty() {
@ -132,7 +133,7 @@ fn remove_newline(
fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> {
let block = ast::Block::cast(node.parent()?)?;
let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
let expr = single_expr(block)?;
let expr = extract_trivial_expression(block)?;
edit.replace(
block_expr.syntax().range(),
expr.syntax().text().to_string(),
@ -140,26 +141,6 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Opti
Some(())
}
fn single_expr(block: &ast::Block) -> Option<&ast::Expr> {
let mut res = None;
for child in block.syntax().children() {
if let Some(expr) = ast::Expr::cast(child) {
if expr.syntax().text().contains('\n') {
return None;
}
if mem::replace(&mut res, Some(expr)).is_some() {
return None;
}
} else {
match child.kind() {
WHITESPACE | L_CURLY | R_CURLY => (),
_ => return None,
}
}
}
res
}
fn join_single_use_tree(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> {
let use_tree_list = ast::UseTreeList::cast(node.parent()?)?;
let (tree,) = use_tree_list.use_trees().collect_tuple()?;
@ -177,29 +158,6 @@ fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
}
}
fn compute_ws(left: &SyntaxNode, right: &SyntaxNode) -> &'static str {
match left.kind() {
L_PAREN | L_BRACK => return "",
L_CURLY => {
if let USE_TREE = right.kind() {
return "";
}
}
_ => (),
}
match right.kind() {
R_PAREN | R_BRACK => return "",
R_CURLY => {
if let USE_TREE = left.kind() {
return "";
}
}
DOT => return "",
_ => (),
}
" "
}
#[cfg(test)]
mod tests {
use crate::test_utils::{assert_eq_text, check_action, extract_range};

View file

@ -14,6 +14,7 @@ mod test_utils;
mod join_lines;
mod typing;
mod diagnostics;
pub(crate) mod formatting;
pub use self::{
assists::LocalEdit,