mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-29 19:17:12 +00:00 
			
		
		
		
	internal: Migrate inline_local_variable to SyntaxEditor
				
					
				
			This commit is contained in:
		
							parent
							
								
									62dea277cc
								
							
						
					
					
						commit
						c6ea7cbafa
					
				
					 2 changed files with 58 additions and 35 deletions
				
			
		|  | @ -5,7 +5,7 @@ use ide_db::{ | ||||||
|     EditionedFileId, RootDatabase, |     EditionedFileId, RootDatabase, | ||||||
| }; | }; | ||||||
| use syntax::{ | use syntax::{ | ||||||
|     ast::{self, AstNode, AstToken, HasName}, |     ast::{self, syntax_factory::SyntaxFactory, AstNode, AstToken, HasName}, | ||||||
|     SyntaxElement, TextRange, |     SyntaxElement, TextRange, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -43,22 +43,6 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) | ||||||
|         }?; |         }?; | ||||||
|     let initializer_expr = let_stmt.initializer()?; |     let initializer_expr = let_stmt.initializer()?; | ||||||
| 
 | 
 | ||||||
|     let delete_range = delete_let.then(|| { |  | ||||||
|         if let Some(whitespace) = let_stmt |  | ||||||
|             .syntax() |  | ||||||
|             .next_sibling_or_token() |  | ||||||
|             .and_then(SyntaxElement::into_token) |  | ||||||
|             .and_then(ast::Whitespace::cast) |  | ||||||
|         { |  | ||||||
|             TextRange::new( |  | ||||||
|                 let_stmt.syntax().text_range().start(), |  | ||||||
|                 whitespace.syntax().text_range().end(), |  | ||||||
|             ) |  | ||||||
|         } else { |  | ||||||
|             let_stmt.syntax().text_range() |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     let wrap_in_parens = references |     let wrap_in_parens = references | ||||||
|         .into_iter() |         .into_iter() | ||||||
|         .filter_map(|FileReference { range, name, .. }| match name { |         .filter_map(|FileReference { range, name, .. }| match name { | ||||||
|  | @ -76,37 +60,55 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>) | ||||||
|             let usage_parent_option = usage_node.and_then(|it| it.parent()); |             let usage_parent_option = usage_node.and_then(|it| it.parent()); | ||||||
|             let usage_parent = match usage_parent_option { |             let usage_parent = match usage_parent_option { | ||||||
|                 Some(u) => u, |                 Some(u) => u, | ||||||
|                 None => return Some((range, name_ref, false)), |                 None => return Some((name_ref, false)), | ||||||
|             }; |             }; | ||||||
|             Some((range, name_ref, initializer_expr.needs_parens_in(&usage_parent))) |             Some((name_ref, initializer_expr.needs_parens_in(&usage_parent))) | ||||||
|         }) |         }) | ||||||
|         .collect::<Option<Vec<_>>>()?; |         .collect::<Option<Vec<_>>>()?; | ||||||
| 
 | 
 | ||||||
|     let init_str = initializer_expr.syntax().text().to_string(); |  | ||||||
|     let init_in_paren = format!("({init_str})"); |  | ||||||
| 
 |  | ||||||
|     let target = match target { |     let target = match target { | ||||||
|         ast::NameOrNameRef::Name(it) => it.syntax().text_range(), |         ast::NameOrNameRef::Name(it) => it.syntax().clone(), | ||||||
|         ast::NameOrNameRef::NameRef(it) => it.syntax().text_range(), |         ast::NameOrNameRef::NameRef(it) => it.syntax().clone(), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     acc.add( |     acc.add( | ||||||
|         AssistId("inline_local_variable", AssistKind::RefactorInline), |         AssistId("inline_local_variable", AssistKind::RefactorInline), | ||||||
|         "Inline variable", |         "Inline variable", | ||||||
|         target, |         target.text_range(), | ||||||
|         move |builder| { |         move |builder| { | ||||||
|             if let Some(range) = delete_range { |             let mut editor = builder.make_editor(&target); | ||||||
|                 builder.delete(range); |             if delete_let { | ||||||
|  |                 editor.delete(let_stmt.syntax()); | ||||||
|  |                 if let Some(whitespace) = let_stmt | ||||||
|  |                     .syntax() | ||||||
|  |                     .next_sibling_or_token() | ||||||
|  |                     .and_then(SyntaxElement::into_token) | ||||||
|  |                     .and_then(ast::Whitespace::cast) | ||||||
|  |                 { | ||||||
|  |                     editor.delete(whitespace.syntax()); | ||||||
|                 } |                 } | ||||||
|             for (range, name, should_wrap) in wrap_in_parens { |             } | ||||||
|                 let replacement = if should_wrap { &init_in_paren } else { &init_str }; | 
 | ||||||
|                 if ast::RecordExprField::for_field_name(&name).is_some() { |             let make = SyntaxFactory::new(); | ||||||
|                     cov_mark::hit!(inline_field_shorthand); | 
 | ||||||
|                     builder.insert(range.end(), format!(": {replacement}")); |             for (name, should_wrap) in wrap_in_parens { | ||||||
|  |                 let replacement = if should_wrap { | ||||||
|  |                     make.expr_paren(initializer_expr.clone()).into() | ||||||
|                 } else { |                 } else { | ||||||
|                     builder.replace(range, replacement.clone()) |                     initializer_expr.clone() | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 if let Some(record_field) = ast::RecordExprField::for_field_name(&name) { | ||||||
|  |                     cov_mark::hit!(inline_field_shorthand); | ||||||
|  |                     let replacement = make.record_expr_field(name, Some(replacement)); | ||||||
|  |                     editor.replace(record_field.syntax(), replacement.syntax()); | ||||||
|  |                 } else { | ||||||
|  |                     editor.replace(name.syntax(), replacement.syntax()); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             editor.add_mappings(make.finish_with_mappings()); | ||||||
|  |             builder.add_file_edits(ctx.file_id(), editor); | ||||||
|         }, |         }, | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -783,6 +783,27 @@ impl SyntaxFactory { | ||||||
|         ast |         ast | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn record_expr_field( | ||||||
|  |         &self, | ||||||
|  |         name: ast::NameRef, | ||||||
|  |         expr: Option<ast::Expr>, | ||||||
|  |     ) -> ast::RecordExprField { | ||||||
|  |         let ast = make::record_expr_field(name.clone(), expr.clone()).clone_for_update(); | ||||||
|  | 
 | ||||||
|  |         if let Some(mut mapping) = self.mappings() { | ||||||
|  |             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); | ||||||
|  | 
 | ||||||
|  |             builder.map_node(name.syntax().clone(), ast.name_ref().unwrap().syntax().clone()); | ||||||
|  |             if let Some(expr) = expr { | ||||||
|  |                 builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             builder.finish(&mut mapping); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ast | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     pub fn record_field_list( |     pub fn record_field_list( | ||||||
|         &self, |         &self, | ||||||
|         fields: impl IntoIterator<Item = ast::RecordField>, |         fields: impl IntoIterator<Item = ast::RecordField>, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Shoyu Vanilla
						Shoyu Vanilla