11use itertools:: Itertools ;
22use syntax:: {
33 ast:: { self , make, AstNode , AstToken } ,
4- match_ast, ted, Edition , NodeOrToken , SyntaxElement , TextRange , TextSize , T ,
4+ match_ast,
5+ syntax_editor:: SyntaxEditor ,
6+ Edition , NodeOrToken , SyntaxElement , TextRange , TextSize , T ,
57} ;
68
79use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
@@ -37,22 +39,18 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
3739 . collect ( )
3840 } ;
3941
40- let replacements =
41- macro_calls. into_iter ( ) . filter_map ( compute_dbg_replacement) . collect :: < Vec < _ > > ( ) ;
42+ let root = match ctx. covering_element ( ) {
43+ NodeOrToken :: Node ( node) => node. ancestors ( ) . last ( ) . unwrap ( ) ,
44+ NodeOrToken :: Token ( token) => token. parent_ancestors ( ) . last ( ) . unwrap ( ) ,
45+ } ;
46+ let mut editor = SyntaxEditor :: new ( root) ;
47+ let replacements = macro_calls. iter ( ) . filter_map ( |mc| run_dbg_replacement ( mc, & mut editor) ) ;
4248
4349 acc. add (
4450 AssistId ( "remove_dbg" , AssistKind :: QuickFix ) ,
4551 "Remove dbg!()" ,
46- replacements. iter ( ) . map ( |& ( range, _) | range) . reduce ( |acc, range| acc. cover ( range) ) ?,
47- |builder| {
48- for ( range, expr) in replacements {
49- if let Some ( expr) = expr {
50- builder. replace ( range, expr. to_string ( ) ) ;
51- } else {
52- builder. delete ( range) ;
53- }
54- }
55- } ,
52+ replacements. map ( |( range, _) | range) . reduce ( |acc, range| acc. cover ( range) ) ?,
53+ |builder| builder. add_file_edits ( ctx. file_id ( ) , editor) ,
5654 )
5755}
5856
@@ -62,7 +60,10 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
6260/// - (`macro_expr` has no parent - is that possible?)
6361///
6462/// Returns `Some(_, None)` when the macro call should just be removed.
65- fn compute_dbg_replacement ( macro_expr : ast:: MacroExpr ) -> Option < ( TextRange , Option < ast:: Expr > ) > {
63+ fn run_dbg_replacement (
64+ macro_expr : & ast:: MacroExpr ,
65+ editor : & mut SyntaxEditor ,
66+ ) -> Option < ( TextRange , Option < ast:: Expr > ) > {
6667 let macro_call = macro_expr. macro_call ( ) ?;
6768 let tt = macro_call. token_tree ( ) ?;
6869 let r_delim = NodeOrToken :: Token ( tt. right_delimiter_token ( ) ?) ;
@@ -92,6 +93,7 @@ fn compute_dbg_replacement(macro_expr: ast::MacroExpr) -> Option<(TextRange, Opt
9293 Some ( start) => range. cover_offset( start) ,
9394 None => range,
9495 } ;
96+ editor. delete( macro_expr. syntax( ) . clone_for_update( ) ) ;
9597 ( range, None )
9698 } ,
9799 ast:: ExprStmt ( it) => {
@@ -100,15 +102,18 @@ fn compute_dbg_replacement(macro_expr: ast::MacroExpr) -> Option<(TextRange, Opt
100102 Some ( start) => range. cover_offset( start) ,
101103 None => range,
102104 } ;
105+ editor. delete( macro_expr. syntax( ) . clone_for_update( ) ) ;
103106 ( range, None )
104107 } ,
105- _ => ( macro_call. syntax( ) . text_range( ) , Some ( make:: ext:: expr_unit( ) ) ) ,
108+ _ => {
109+ editor. replace( macro_call. syntax( ) , make:: ext:: expr_unit( ) . syntax( ) . clone_for_update( ) ) ;
110+ ( macro_call. syntax( ) . text_range( ) , Some ( make:: ext:: expr_unit( ) ) )
111+ } ,
106112 }
107113 }
108114 }
109115 // dbg!(expr0)
110116 [ expr] => {
111- // dbg!(expr, &parent);
112117 let wrap = match ast:: Expr :: cast ( parent) {
113118 Some ( parent) => match ( expr, parent) {
114119 ( ast:: Expr :: CastExpr ( _) , ast:: Expr :: CastExpr ( _) ) => false ,
@@ -144,25 +149,27 @@ fn compute_dbg_replacement(macro_expr: ast::MacroExpr) -> Option<(TextRange, Opt
144149 } ,
145150 None => false ,
146151 } ;
147- let expr = replace_nested_dbgs ( expr. clone ( ) ) ;
148- let expr = if wrap { make:: expr_paren ( expr) } else { expr. clone_subtree ( ) } ;
152+ let expr = replace_nested_dbgs ( expr. clone ( ) , editor) ;
153+ let expr = if wrap { make:: expr_paren ( expr. clone ( ) ) } else { expr. clone_subtree ( ) } ;
154+ editor. replace ( macro_call. syntax ( ) , expr. syntax ( ) . clone_for_update ( ) ) ;
149155 ( macro_call. syntax ( ) . text_range ( ) , Some ( expr) )
150156 }
151157 // dbg!(expr0, expr1, ...)
152158 exprs => {
153- let exprs = exprs. iter ( ) . cloned ( ) . map ( replace_nested_dbgs) ;
159+ let exprs = exprs. iter ( ) . map ( |expr| replace_nested_dbgs ( expr . clone ( ) , editor ) ) ;
154160 let expr = make:: expr_tuple ( exprs) ;
161+ editor. replace ( macro_call. syntax ( ) , expr. syntax ( ) . clone_for_update ( ) ) ;
155162 ( macro_call. syntax ( ) . text_range ( ) , Some ( expr. into ( ) ) )
156163 }
157164 } )
158165}
159166
160- fn replace_nested_dbgs ( expanded : ast:: Expr ) -> ast:: Expr {
167+ fn replace_nested_dbgs ( expanded : ast:: Expr , editor : & mut SyntaxEditor ) -> ast:: Expr {
161168 if let ast:: Expr :: MacroExpr ( mac) = & expanded {
162169 // Special-case when `expanded` itself is `dbg!()` since we cannot replace the whole tree
163170 // with `ted`. It should be fairly rare as it means the user wrote `dbg!(dbg!(..))` but you
164171 // never know how code ends up being!
165- let replaced = if let Some ( ( _, expr_opt) ) = compute_dbg_replacement ( mac. clone ( ) ) {
172+ let replaced = if let Some ( ( _, expr_opt) ) = run_dbg_replacement ( mac, editor ) {
166173 match expr_opt {
167174 Some ( expr) => expr,
168175 None => {
@@ -177,22 +184,18 @@ fn replace_nested_dbgs(expanded: ast::Expr) -> ast::Expr {
177184 return replaced;
178185 }
179186
180- let expanded = expanded. clone_for_update ( ) ;
181-
182- // We need to collect to avoid mutation during traversal.
183- let macro_exprs: Vec < _ > =
184- expanded. syntax ( ) . descendants ( ) . filter_map ( ast:: MacroExpr :: cast) . collect ( ) ;
187+ let macro_exprs = expanded. syntax ( ) . descendants ( ) . filter_map ( ast:: MacroExpr :: cast) ;
185188
186189 for mac in macro_exprs {
187- let expr_opt = match compute_dbg_replacement ( mac. clone ( ) ) {
190+ let expr_opt = match run_dbg_replacement ( & mac, editor ) {
188191 Some ( ( _, expr) ) => expr,
189192 None => continue ,
190193 } ;
191194
192195 if let Some ( expr) = expr_opt {
193- ted :: replace ( mac. syntax ( ) , expr. syntax ( ) . clone_for_update ( ) ) ;
196+ editor . replace ( mac. syntax ( ) , expr. syntax ( ) . clone_for_update ( ) ) ;
194197 } else {
195- ted :: remove ( mac. syntax ( ) ) ;
198+ editor . delete ( mac. syntax ( ) ) ;
196199 }
197200 }
198201
0 commit comments