Skip to content

Commit 6a08a54

Browse files
committed
remove set_pat from edit_in_place and move set_pat_with_editor in edit
1 parent bb0e103 commit 6a08a54

2 files changed

Lines changed: 66 additions & 130 deletions

File tree

crates/syntax/src/ast/edit.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
//! This module contains functions for editing syntax trees. As the trees are
22
//! immutable, all function here return a fresh copy of the tree, instead of
33
//! doing an in-place modification.
4+
use parser::T;
45
use std::{fmt, iter, ops};
56

67
use crate::{
7-
AstToken, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
8-
ast::{self, AstNode, make},
9-
syntax_editor::{SyntaxEditor, SyntaxMappingBuilder},
8+
AstToken, NodeOrToken, SyntaxElement,
9+
SyntaxKind::WHITESPACE,
10+
SyntaxNode, SyntaxToken,
11+
ast::{self, AstNode, HasName, make},
12+
syntax_editor::{Position, SyntaxEditor, SyntaxMappingBuilder},
1013
ted,
1114
};
1215

@@ -194,6 +197,65 @@ pub trait AstNodeEdit: AstNode + Clone + Sized {
194197

195198
impl<N: AstNode + Clone> AstNodeEdit for N {}
196199

200+
impl ast::IdentPat {
201+
pub fn set_pat_with_editor(
202+
&self,
203+
pat: Option<ast::Pat>,
204+
syntax_editor: &mut SyntaxEditor,
205+
syntax_factory: &SyntaxFactory,
206+
) -> ast::IdentPat {
207+
match pat {
208+
None => {
209+
if let Some(at_token) = self.at_token() {
210+
// Remove `@ Pat`
211+
let start = at_token.clone().into();
212+
let end = self
213+
.pat()
214+
.map(|it| it.syntax().clone().into())
215+
.unwrap_or_else(|| at_token.into());
216+
syntax_editor.delete_all(start..=end);
217+
218+
// Remove any trailing ws
219+
if let Some(last) =
220+
self.syntax().last_token().filter(|it| it.kind() == WHITESPACE)
221+
{
222+
last.detach();
223+
}
224+
}
225+
}
226+
Some(pat) => {
227+
if let Some(old_pat) = self.pat() {
228+
// Replace existing pattern
229+
syntax_editor.replace(old_pat.syntax(), pat.syntax())
230+
} else if let Some(at_token) = self.at_token() {
231+
// Have an `@` token but not a pattern yet
232+
syntax_editor.insert(Position::after(at_token), pat.syntax());
233+
} else {
234+
// Don't have an `@`, should have a name
235+
let name = self.name().unwrap();
236+
let elements = vec![
237+
syntax_factory.whitespace(" ").into(),
238+
syntax_factory.token(T![@]).into(),
239+
syntax_factory.whitespace(" ").into(),
240+
pat.syntax().clone().into(),
241+
];
242+
243+
if self.syntax().parent().is_none() {
244+
let (mut local, local_self) = SyntaxEditor::with_ast_node(self);
245+
let local_name = local_self.name().unwrap();
246+
local.insert_all(Position::after(local_name.syntax()), elements);
247+
let edit = local.finish();
248+
return ast::IdentPat::cast(edit.new_root().clone()).unwrap();
249+
} else {
250+
syntax_editor.insert_all(Position::after(name.syntax()), elements);
251+
}
252+
}
253+
}
254+
}
255+
self.clone()
256+
}
257+
}
258+
197259
#[test]
198260
fn test_increase_indent() {
199261
let arm_list = {

crates/syntax/src/ast/edit_in_place.rs

Lines changed: 1 addition & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ use crate::{
99
SyntaxKind::{ATTR, COMMENT, WHITESPACE},
1010
SyntaxNode, SyntaxToken,
1111
algo::{self, neighbor},
12-
ast::{self, edit::IndentLevel, make, syntax_factory::SyntaxFactory},
13-
syntax_editor::{Position, SyntaxEditor},
12+
ast::{self, edit::IndentLevel, make},
1413
ted,
1514
};
1615

@@ -528,103 +527,6 @@ fn normalize_ws_between_braces(node: &SyntaxNode) -> Option<()> {
528527
Some(())
529528
}
530529

531-
impl ast::IdentPat {
532-
pub fn set_pat(&self, pat: Option<ast::Pat>) {
533-
match pat {
534-
None => {
535-
if let Some(at_token) = self.at_token() {
536-
// Remove `@ Pat`
537-
let start = at_token.clone().into();
538-
let end = self
539-
.pat()
540-
.map(|it| it.syntax().clone().into())
541-
.unwrap_or_else(|| at_token.into());
542-
543-
ted::remove_all(start..=end);
544-
545-
// Remove any trailing ws
546-
if let Some(last) =
547-
self.syntax().last_token().filter(|it| it.kind() == WHITESPACE)
548-
{
549-
last.detach();
550-
}
551-
}
552-
}
553-
Some(pat) => {
554-
if let Some(old_pat) = self.pat() {
555-
// Replace existing pattern
556-
ted::replace(old_pat.syntax(), pat.syntax())
557-
} else if let Some(at_token) = self.at_token() {
558-
// Have an `@` token but not a pattern yet
559-
ted::insert(ted::Position::after(at_token), pat.syntax());
560-
} else {
561-
// Don't have an `@`, should have a name
562-
let name = self.name().unwrap();
563-
564-
ted::insert_all(
565-
ted::Position::after(name.syntax()),
566-
vec![
567-
make::token(T![@]).into(),
568-
make::tokens::single_space().into(),
569-
pat.syntax().clone().into(),
570-
],
571-
)
572-
}
573-
}
574-
}
575-
}
576-
577-
pub fn set_pat_with_editor(
578-
&self,
579-
pat: Option<ast::Pat>,
580-
syntax_editor: &mut SyntaxEditor,
581-
syntax_factory: &SyntaxFactory,
582-
) {
583-
match pat {
584-
None => {
585-
if let Some(at_token) = self.at_token() {
586-
// Remove `@ Pat`
587-
let start = at_token.clone().into();
588-
let end = self
589-
.pat()
590-
.map(|it| it.syntax().clone().into())
591-
.unwrap_or_else(|| at_token.into());
592-
syntax_editor.delete_all(start..=end);
593-
594-
// Remove any trailing ws
595-
if let Some(last) =
596-
self.syntax().last_token().filter(|it| it.kind() == WHITESPACE)
597-
{
598-
last.detach();
599-
}
600-
}
601-
}
602-
Some(pat) => {
603-
if let Some(old_pat) = self.pat() {
604-
// Replace existing pattern
605-
syntax_editor.replace(old_pat.syntax(), pat.syntax())
606-
} else if let Some(at_token) = self.at_token() {
607-
// Have an `@` token but not a pattern yet
608-
syntax_editor.insert(Position::after(at_token), pat.syntax());
609-
} else {
610-
// Don't have an `@`, should have a name
611-
let name = self.name().unwrap();
612-
613-
syntax_editor.insert_all(
614-
Position::after(name.syntax()),
615-
vec![
616-
syntax_factory.whitespace(" ").into(),
617-
syntax_factory.token(T![@]).into(),
618-
syntax_factory.whitespace(" ").into(),
619-
pat.syntax().clone().into(),
620-
],
621-
)
622-
}
623-
}
624-
}
625-
}
626-
}
627-
628530
pub trait Indent: AstNode + Clone + Sized {
629531
fn indent_level(&self) -> IndentLevel {
630532
IndentLevel::from_node(self.syntax())
@@ -674,32 +576,4 @@ mod tests {
674576
}",
675577
);
676578
}
677-
678-
#[test]
679-
fn test_ident_pat_set_pat() {
680-
#[track_caller]
681-
fn check(before: &str, expected: &str, pat: Option<ast::Pat>) {
682-
let pat = pat.map(|it| it.clone_for_update());
683-
684-
let ident_pat = ast_mut_from_text::<ast::IdentPat>(&format!("fn f() {{ {before} }}"));
685-
ident_pat.set_pat(pat);
686-
687-
let after = ast_mut_from_text::<ast::IdentPat>(&format!("fn f() {{ {expected} }}"));
688-
assert_eq!(ident_pat.to_string(), after.to_string());
689-
}
690-
691-
// replacing
692-
check("let a @ _;", "let a @ ();", Some(make::tuple_pat([]).into()));
693-
694-
// note: no trailing semicolon is added for the below tests since it
695-
// seems to be picked up by the ident pat during error recovery?
696-
697-
// adding
698-
check("let a ", "let a @ ()", Some(make::tuple_pat([]).into()));
699-
check("let a @ ", "let a @ ()", Some(make::tuple_pat([]).into()));
700-
701-
// removing
702-
check("let a @ ()", "let a", None);
703-
check("let a @ ", "let a", None);
704-
}
705579
}

0 commit comments

Comments
 (0)