fix: migrate unmerge_use to syntax editor

Also ensures that attributes on the use item are applied to the new use
item when unmerging.

Signed-off-by: Prajwal S N <prajwalnadig21@gmail.com>
This commit is contained in:
Prajwal S N 2025-03-28 03:15:10 +05:30
parent 5adee2ad2c
commit bb493649d2
No known key found for this signature in database
GPG key ID: 60701A603988FAC2
4 changed files with 108 additions and 16 deletions

View file

@ -107,6 +107,20 @@ impl SyntaxFactory {
ast
}
pub fn use_(&self, visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use {
make::use_(visibility, use_tree).clone_for_update()
}
pub fn use_tree(
&self,
path: ast::Path,
use_tree_list: Option<ast::UseTreeList>,
alias: Option<ast::Rename>,
add_star: bool,
) -> ast::UseTree {
make::use_tree(path, use_tree_list, alias, add_star).clone_for_update()
}
pub fn path_unqualified(&self, segment: ast::PathSegment) -> ast::Path {
let ast = make::path_unqualified(segment.clone()).clone_for_update();

View file

@ -20,6 +20,7 @@ mod edit_algo;
mod edits;
mod mapping;
pub use edits::Removable;
pub use mapping::{SyntaxMapping, SyntaxMappingBuilder};
#[derive(Debug)]

View file

@ -1,7 +1,8 @@
//! Structural editing for ast using `SyntaxEditor`
use crate::{
Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T,
AstToken, Direction, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, T,
algo::neighbor,
ast::{
self, AstNode, Fn, GenericParam, HasGenericParams, HasName, edit::IndentLevel, make,
syntax_factory::SyntaxFactory,
@ -143,6 +144,53 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) ->
Some(())
}
pub trait Removable: AstNode {
fn remove(&self, editor: &mut SyntaxEditor);
}
impl Removable for ast::Use {
fn remove(&self, editor: &mut SyntaxEditor) {
let make = SyntaxFactory::without_mappings();
let next_ws = self
.syntax()
.next_sibling_or_token()
.and_then(|it| it.into_token())
.and_then(ast::Whitespace::cast);
if let Some(next_ws) = next_ws {
let ws_text = next_ws.syntax().text();
if let Some(rest) = ws_text.strip_prefix('\n') {
if rest.is_empty() {
editor.delete(next_ws.syntax());
} else {
editor.replace(next_ws.syntax(), make.whitespace(rest));
}
}
}
editor.delete(self.syntax());
}
}
impl Removable for ast::UseTree {
fn remove(&self, editor: &mut SyntaxEditor) {
for dir in [Direction::Next, Direction::Prev] {
if let Some(next_use_tree) = neighbor(self, dir) {
let separators = self
.syntax()
.siblings_with_tokens(dir)
.skip(1)
.take_while(|it| it.as_node() != Some(next_use_tree.syntax()));
for sep in separators {
editor.delete(sep);
}
break;
}
}
editor.delete(self.syntax());
}
}
#[cfg(test)]
mod tests {
use parser::Edition;