More fluent indent API

This commit is contained in:
Aleksey Kladov 2020-05-09 14:40:11 +02:00
parent c6334285e3
commit 231fddab54
7 changed files with 45 additions and 34 deletions

View file

@ -1,7 +1,11 @@
use hir::HirDisplay;
use ra_db::FileId;
use ra_syntax::{
ast::{self, edit::IndentLevel, ArgListOwner, AstNode, ModuleItemOwner},
ast::{
self,
edit::{AstNodeEdit, IndentLevel},
ArgListOwner, AstNode, ModuleItemOwner,
},
SyntaxKind, SyntaxNode, TextSize,
};
use rustc_hash::{FxHashMap, FxHashSet};
@ -116,17 +120,16 @@ impl FunctionBuilder {
let (fn_def, insert_offset) = match self.target {
GeneratedFunctionTarget::BehindItem(it) => {
let with_leading_blank_line = ast::make::add_leading_newlines(2, fn_def);
let indented = IndentLevel::from_node(&it).increase_indent(with_leading_blank_line);
let indented = with_leading_blank_line.indent(IndentLevel::from_node(&it));
(indented, it.text_range().end())
}
GeneratedFunctionTarget::InEmptyItemList(it) => {
let indent_once = IndentLevel(1);
let indent = IndentLevel::from_node(it.syntax());
let fn_def = ast::make::add_leading_newlines(1, fn_def);
let fn_def = indent_once.increase_indent(fn_def);
let fn_def = fn_def.indent(indent_once);
let fn_def = ast::make::add_trailing_newlines(1, fn_def);
let fn_def = indent.increase_indent(fn_def);
let fn_def = fn_def.indent(indent);
(fn_def, it.syntax().text_range().start() + TextSize::of('{'))
}
};

View file

@ -2,7 +2,7 @@ use hir::HasSource;
use ra_syntax::{
ast::{
self,
edit::{self, IndentLevel},
edit::{self, AstNodeEdit, IndentLevel},
make, AstNode, NameOwner,
},
SmolStr,
@ -176,8 +176,7 @@ fn add_body(fn_def: ast::FnDef) -> ast::FnDef {
if fn_def.body().is_some() {
return fn_def;
}
let body = make::block_expr(None, Some(make::expr_todo()));
let body = IndentLevel(1).increase_indent(body);
let body = make::block_expr(None, Some(make::expr_todo())).indent(IndentLevel(1));
fn_def.with_body(body)
}

View file

@ -2,7 +2,11 @@ use std::{iter::once, ops::RangeInclusive};
use ra_syntax::{
algo::replace_children,
ast::{self, edit::IndentLevel, make},
ast::{
self,
edit::{AstNodeEdit, IndentLevel},
make,
},
AstNode,
SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE},
SyntaxNode,
@ -105,8 +109,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
let then_branch =
make::block_expr(once(make::expr_stmt(early_expression).into()), None);
let cond = invert_boolean_expression(cond_expr);
let e = make::expr_if(make::condition(cond, None), then_branch);
if_indent_level.increase_indent(e)
make::expr_if(make::condition(cond, None), then_branch).indent(if_indent_level)
};
replace(new_expr.syntax(), &then_block, &parent_block, &if_expr)
}
@ -140,7 +143,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
make::bind_pat(make::name(&bound_ident.syntax().to_string())).into(),
Some(match_expr),
);
let let_stmt = if_indent_level.increase_indent(let_stmt);
let let_stmt = let_stmt.indent(if_indent_level);
replace(let_stmt.syntax(), &then_block, &parent_block, &if_expr)
}
};
@ -153,7 +156,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
parent_block: &ast::BlockExpr,
if_expr: &ast::IfExpr,
) -> SyntaxNode {
let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone());
let then_block_items = then_block.unindent(IndentLevel::from(1));
let end_of_then = then_block_items.syntax().last_child_or_token().unwrap();
let end_of_then =
if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {

View file

@ -1,6 +1,10 @@
use ra_fmt::unwrap_trivial_block;
use ra_syntax::{
ast::{self, edit::IndentLevel, make},
ast::{
self,
edit::{AstNodeEdit, IndentLevel},
make,
},
AstNode,
};
@ -61,10 +65,9 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext)
make::match_arm(vec![pattern], else_expr)
};
make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm]))
.indent(IndentLevel::from_node(if_expr.syntax()))
};
let match_expr = IndentLevel::from_node(if_expr.syntax()).increase_indent(match_expr);
edit.set_cursor(if_expr.syntax().text_range().start());
edit.replace_ast::<ast::Expr>(if_expr.into(), match_expr);
})

View file

@ -53,8 +53,7 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
)
.into(),
};
let block =
IndentLevel::from_node(let_stmt.syntax()).increase_indent(make::block_expr(None, None));
let block = make::block_expr(None, None).indent(IndentLevel::from_node(let_stmt.syntax()));
let if_ = make::expr_if(make::condition(init, Some(with_placeholder)), block);
let stmt = make::expr_stmt(if_);

View file

@ -1,7 +1,11 @@
use std::iter;
use ra_syntax::{
ast::{self, edit::IndentLevel, make},
ast::{
self,
edit::{AstNodeEdit, IndentLevel},
make,
},
AstNode,
};
@ -51,8 +55,8 @@ pub(crate) fn replace_unwrap_with_match(acc: &mut Assists, ctx: &AssistContext)
let err_arm = make::match_arm(iter::once(make::placeholder_pat().into()), unreachable_call);
let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]);
let match_expr = make::expr_match(caller.clone(), match_arm_list);
let match_expr = IndentLevel::from_node(method_call.syntax()).increase_indent(match_expr);
let match_expr = make::expr_match(caller.clone(), match_arm_list)
.indent(IndentLevel::from_node(method_call.syntax()));
edit.set_cursor(caller.syntax().text_range().start());
edit.replace_ast::<ast::Expr>(method_call.into(), match_expr);

View file

@ -453,11 +453,7 @@ impl IndentLevel {
IndentLevel(0)
}
pub fn increase_indent<N: AstNode>(self, node: N) -> N {
N::cast(self._increase_indent(node.syntax().clone())).unwrap()
}
fn _increase_indent(self, node: SyntaxNode) -> SyntaxNode {
fn increase_indent(self, node: SyntaxNode) -> SyntaxNode {
let mut rewriter = SyntaxRewriter::default();
node.descendants_with_tokens()
.filter_map(|el| el.into_token())
@ -478,11 +474,7 @@ impl IndentLevel {
rewriter.rewrite(&node)
}
pub fn decrease_indent<N: AstNode>(self, node: N) -> N {
N::cast(self._decrease_indent(node.syntax().clone())).unwrap()
}
fn _decrease_indent(self, node: SyntaxNode) -> SyntaxNode {
fn decrease_indent(self, node: SyntaxNode) -> SyntaxNode {
let mut rewriter = SyntaxRewriter::default();
node.descendants_with_tokens()
.filter_map(|el| el.into_token())
@ -521,7 +513,7 @@ fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
iter::successors(Some(token), |token| token.prev_token())
}
pub trait AstNodeEdit: AstNode + Sized {
pub trait AstNodeEdit: AstNode + Clone + Sized {
#[must_use]
fn insert_children(
&self,
@ -558,9 +550,17 @@ pub trait AstNodeEdit: AstNode + Sized {
}
rewriter.rewrite_ast(self)
}
#[must_use]
fn indent(&self, indent: IndentLevel) -> Self {
Self::cast(indent.increase_indent(self.syntax().clone())).unwrap()
}
#[must_use]
fn unindent(&self, indent: IndentLevel) -> Self {
Self::cast(indent.decrease_indent(self.syntax().clone())).unwrap()
}
}
impl<N: AstNode> AstNodeEdit for N {}
impl<N: AstNode + Clone> AstNodeEdit for N {}
fn single_node(element: impl Into<SyntaxElement>) -> RangeInclusive<SyntaxElement> {
let element = element.into();
@ -580,7 +580,7 @@ fn test_increase_indent() {
_ => (),
}"
);
let indented = IndentLevel(2).increase_indent(arm_list);
let indented = arm_list.indent(IndentLevel(2));
assert_eq!(
indented.syntax().to_string(),
"{