mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Make "pull assignments up" assist work in more cases
This commit is contained in:
		
							parent
							
								
									6cd11bbbc2
								
							
						
					
					
						commit
						5f37e34406
					
				@ -60,6 +60,12 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
 | 
				
			|||||||
        return None;
 | 
					        return None;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Some(parent) = tgt.syntax().parent() {
 | 
				
			||||||
 | 
					        if matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT) {
 | 
				
			||||||
 | 
					            return None;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    acc.add(
 | 
					    acc.add(
 | 
				
			||||||
        AssistId("pull_assignment_up", AssistKind::RefactorExtract),
 | 
					        AssistId("pull_assignment_up", AssistKind::RefactorExtract),
 | 
				
			||||||
        "Pull assignment up",
 | 
					        "Pull assignment up",
 | 
				
			||||||
@ -74,7 +80,13 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
 | 
				
			|||||||
            let tgt = edit.make_ast_mut(tgt);
 | 
					            let tgt = edit.make_ast_mut(tgt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (stmt, rhs) in assignments {
 | 
					            for (stmt, rhs) in assignments {
 | 
				
			||||||
                ted::replace(stmt.syntax(), rhs.syntax());
 | 
					                let mut stmt = stmt.syntax().clone();
 | 
				
			||||||
 | 
					                if let Some(parent) = stmt.parent() {
 | 
				
			||||||
 | 
					                    if ast::ExprStmt::cast(parent.clone()).is_some() {
 | 
				
			||||||
 | 
					                        stmt = parent.clone();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ted::replace(stmt, rhs.syntax());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            let assign_expr = make::expr_assignment(collector.common_lhs, tgt.clone());
 | 
					            let assign_expr = make::expr_assignment(collector.common_lhs, tgt.clone());
 | 
				
			||||||
            let assign_stmt = make::expr_stmt(assign_expr);
 | 
					            let assign_stmt = make::expr_stmt(assign_expr);
 | 
				
			||||||
@ -87,7 +99,7 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti
 | 
				
			|||||||
struct AssignmentsCollector<'a> {
 | 
					struct AssignmentsCollector<'a> {
 | 
				
			||||||
    sema: &'a hir::Semantics<'a, ide_db::RootDatabase>,
 | 
					    sema: &'a hir::Semantics<'a, ide_db::RootDatabase>,
 | 
				
			||||||
    common_lhs: ast::Expr,
 | 
					    common_lhs: ast::Expr,
 | 
				
			||||||
    assignments: Vec<(ast::ExprStmt, ast::Expr)>,
 | 
					    assignments: Vec<(ast::BinExpr, ast::Expr)>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> AssignmentsCollector<'a> {
 | 
					impl<'a> AssignmentsCollector<'a> {
 | 
				
			||||||
@ -95,6 +107,7 @@ impl<'a> AssignmentsCollector<'a> {
 | 
				
			|||||||
        for arm in match_expr.match_arm_list()?.arms() {
 | 
					        for arm in match_expr.match_arm_list()?.arms() {
 | 
				
			||||||
            match arm.expr()? {
 | 
					            match arm.expr()? {
 | 
				
			||||||
                ast::Expr::BlockExpr(block) => self.collect_block(&block)?,
 | 
					                ast::Expr::BlockExpr(block) => self.collect_block(&block)?,
 | 
				
			||||||
 | 
					                ast::Expr::BinExpr(expr) => self.collect_expr(&expr)?,
 | 
				
			||||||
                _ => return None,
 | 
					                _ => return None,
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -114,24 +127,30 @@ impl<'a> AssignmentsCollector<'a> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn collect_block(&mut self, block: &ast::BlockExpr) -> Option<()> {
 | 
					    fn collect_block(&mut self, block: &ast::BlockExpr) -> Option<()> {
 | 
				
			||||||
        if block.tail_expr().is_some() {
 | 
					        let last_expr = block.tail_expr().or_else(|| {
 | 
				
			||||||
            return None;
 | 
					            if let ast::Stmt::ExprStmt(stmt) = block.statements().last()? {
 | 
				
			||||||
        }
 | 
					                stmt.expr()
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
        let last_stmt = block.statements().last()?;
 | 
					                None
 | 
				
			||||||
        if let ast::Stmt::ExprStmt(stmt) = last_stmt {
 | 
					 | 
				
			||||||
            if let ast::Expr::BinExpr(expr) = stmt.expr()? {
 | 
					 | 
				
			||||||
                if expr.op_kind()? == ast::BinOp::Assignment
 | 
					 | 
				
			||||||
                    && is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    self.assignments.push((stmt, expr.rhs()?));
 | 
					 | 
				
			||||||
                    return Some(());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let ast::Expr::BinExpr(expr) = last_expr {
 | 
				
			||||||
 | 
					            return self.collect_expr(&expr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn collect_expr(&mut self, expr: &ast::BinExpr) -> Option<()> {
 | 
				
			||||||
 | 
					        if expr.op_kind()? == ast::BinOp::Assignment
 | 
				
			||||||
 | 
					            && is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            self.assignments.push((expr.clone(), expr.rhs()?));
 | 
				
			||||||
 | 
					            return Some(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        None
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn is_equivalent(
 | 
					fn is_equivalent(
 | 
				
			||||||
@ -241,7 +260,6 @@ fn foo() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    #[ignore]
 | 
					 | 
				
			||||||
    fn test_pull_assignment_up_assignment_expressions() {
 | 
					    fn test_pull_assignment_up_assignment_expressions() {
 | 
				
			||||||
        check_assist(
 | 
					        check_assist(
 | 
				
			||||||
            pull_assignment_up,
 | 
					            pull_assignment_up,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user