Skip to content

Commit d6c4165

Browse files
committed
internal: introduce in-place indenting API
1 parent dcbaa75 commit d6c4165

File tree

2 files changed

+61
-18
lines changed

2 files changed

+61
-18
lines changed

crates/syntax/src/ast/edit.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,8 @@ impl IndentLevel {
117117
/// }
118118
/// ```
119119
/// if you indent the block, the `{` token would stay put.
120-
fn increase_indent(self, node: SyntaxNode) -> SyntaxNode {
121-
let res = node.clone_subtree().clone_for_update();
122-
let tokens = res.preorder_with_tokens().filter_map(|event| match event {
120+
pub(in super) fn increase_indent(self, node: &SyntaxNode) {
121+
let tokens = node.preorder_with_tokens().filter_map(|event| match event {
123122
rowan::WalkEvent::Leave(NodeOrToken::Token(it)) => Some(it),
124123
_ => None,
125124
});
@@ -131,12 +130,10 @@ impl IndentLevel {
131130
}
132131
}
133132
}
134-
res.clone_subtree()
135133
}
136134

137-
fn decrease_indent(self, node: SyntaxNode) -> SyntaxNode {
138-
let res = node.clone_subtree().clone_for_update();
139-
let tokens = res.preorder_with_tokens().filter_map(|event| match event {
135+
pub(in super) fn decrease_indent(self, node: &SyntaxNode) {
136+
let tokens = node.preorder_with_tokens().filter_map(|event| match event {
140137
rowan::WalkEvent::Leave(NodeOrToken::Token(it)) => Some(it),
141138
_ => None,
142139
});
@@ -150,25 +147,37 @@ impl IndentLevel {
150147
}
151148
}
152149
}
153-
res.clone_subtree()
154150
}
155151
}
156152

157153
fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
158154
iter::successors(Some(token), |token| token.prev_token())
159155
}
160156

157+
/// Soft-deprecated in favor of mutable tree editing API `edit_in_place::Ident`.
161158
pub trait AstNodeEdit: AstNode + Clone + Sized {
162159
fn indent_level(&self) -> IndentLevel {
163160
IndentLevel::from_node(self.syntax())
164161
}
165162
#[must_use]
166163
fn indent(&self, level: IndentLevel) -> Self {
167-
Self::cast(level.increase_indent(self.syntax().clone())).unwrap()
164+
fn indent_inner(node: &SyntaxNode, level: IndentLevel) -> SyntaxNode {
165+
let res = node.clone_subtree().clone_for_update();
166+
level.increase_indent(&res);
167+
res.clone_subtree()
168+
}
169+
170+
Self::cast(indent_inner(self.syntax(), level)).unwrap()
168171
}
169172
#[must_use]
170173
fn dedent(&self, level: IndentLevel) -> Self {
171-
Self::cast(level.decrease_indent(self.syntax().clone())).unwrap()
174+
fn dedent_inner(node: &SyntaxNode, level: IndentLevel) -> SyntaxNode {
175+
let res = node.clone_subtree().clone_for_update();
176+
level.decrease_indent(&res);
177+
res.clone_subtree()
178+
}
179+
180+
Self::cast(dedent_inner(self.syntax(), level)).unwrap()
172181
}
173182
#[must_use]
174183
fn reset_indent(&self) -> Self {

crates/syntax/src/ast/edit_in_place.rs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ use rowan::SyntaxElement;
77

88
use crate::{
99
algo::neighbor,
10-
ast::{
11-
self,
12-
edit::{AstNodeEdit, IndentLevel},
13-
make, GenericParamsOwner,
14-
},
10+
ast::{self, edit::IndentLevel, make, GenericParamsOwner},
1511
ted::{self, Position},
1612
AstNode, AstToken, Direction,
1713
SyntaxKind::{ATTR, COMMENT, WHITESPACE},
@@ -20,7 +16,7 @@ use crate::{
2016

2117
use super::NameOwner;
2218

23-
pub trait GenericParamsOwnerEdit: ast::GenericParamsOwner + AstNodeEdit {
19+
pub trait GenericParamsOwnerEdit: ast::GenericParamsOwner {
2420
fn get_or_create_generic_param_list(&self) -> ast::GenericParamList;
2521
fn get_or_create_where_clause(&self) -> ast::WhereClause;
2622
}
@@ -198,7 +194,7 @@ fn create_generic_param_list(position: Position) -> ast::GenericParamList {
198194
gpl
199195
}
200196

201-
pub trait AttrsOwnerEdit: ast::AttrsOwner + AstNodeEdit {
197+
pub trait AttrsOwnerEdit: ast::AttrsOwner {
202198
fn remove_attrs_and_docs(&self) {
203199
remove_attrs_and_docs(self.syntax());
204200

@@ -222,7 +218,7 @@ pub trait AttrsOwnerEdit: ast::AttrsOwner + AstNodeEdit {
222218
}
223219
}
224220

225-
impl<T: ast::AttrsOwner + AstNodeEdit> AttrsOwnerEdit for T {}
221+
impl<T: ast::AttrsOwner> AttrsOwnerEdit for T {}
226222

227223
impl ast::GenericParamList {
228224
pub fn add_generic_param(&self, generic_param: ast::GenericParam) {
@@ -487,6 +483,26 @@ fn normalize_ws_between_braces(node: &SyntaxNode) -> Option<()> {
487483
Some(())
488484
}
489485

486+
pub trait Indent: AstNode + Clone + Sized {
487+
fn indent_level(&self) -> IndentLevel {
488+
IndentLevel::from_node(self.syntax())
489+
}
490+
fn indent(&self, level: IndentLevel) -> &Self {
491+
level.increase_indent(self.syntax());
492+
self
493+
}
494+
fn dedent(&self, level: IndentLevel) -> &Self {
495+
level.decrease_indent(self.syntax());
496+
self
497+
}
498+
fn reset_indent(&self) -> &Self {
499+
let level = IndentLevel::from_node(self.syntax());
500+
self.dedent(level)
501+
}
502+
}
503+
504+
impl<N: AstNode + Clone> Indent for N {}
505+
490506
#[cfg(test)]
491507
mod tests {
492508
use std::fmt;
@@ -526,4 +542,22 @@ mod tests {
526542
check_create_gpl::<ast::Enum>("enum E", "enum E<>");
527543
check_create_gpl::<ast::Enum>("enum E {", "enum E<> {");
528544
}
545+
546+
#[test]
547+
fn test_increase_indent() {
548+
let arm_list = ast_mut_from_text::<ast::Fn>(
549+
"fn foo() {
550+
;
551+
;
552+
}",
553+
);
554+
arm_list.indent(IndentLevel(2));
555+
assert_eq!(
556+
arm_list.to_string(),
557+
"fn foo() {
558+
;
559+
;
560+
}",
561+
);
562+
}
529563
}

0 commit comments

Comments
 (0)