fix: "Extract to function" assist preserves break and continue labels

Adds a label / lifetime parameter to `ide_assists::handlers::extract_function::FlowKind::{Break, Continue}`, adds support for emitting labels to `syntax::ast::make::{expr_break, expr_continue}`, and implements the required machinery to let `extract_function` make use of them.

This does modify the external API of the `syntax` crate, but the changes there are simple, not used outside `ide_assists`, and, well, we should probably support emitting `break` and `continue` labels through `syntax` anyways, they're part of the language spec.

Closes #11413.
This commit is contained in:
Morgan Thomas 2022-03-12 08:44:37 -08:00
parent 5fcf979f8a
commit 3fafbca32e
4 changed files with 146 additions and 26 deletions

View file

@ -368,18 +368,28 @@ pub fn expr_empty_block() -> ast::Expr {
pub fn expr_path(path: ast::Path) -> ast::Expr {
expr_from_text(&path.to_string())
}
pub fn expr_continue() -> ast::Expr {
expr_from_text("continue")
pub fn expr_continue(label: Option<ast::Lifetime>) -> ast::Expr {
match label {
Some(label) => expr_from_text(&format!("continue {}", label)),
None => expr_from_text("continue"),
}
}
// Consider `op: SyntaxKind` instead for nicer syntax at the call-site?
pub fn expr_bin_op(lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr {
expr_from_text(&format!("{} {} {}", lhs, op, rhs))
}
pub fn expr_break(expr: Option<ast::Expr>) -> ast::Expr {
match expr {
Some(expr) => expr_from_text(&format!("break {}", expr)),
None => expr_from_text("break"),
pub fn expr_break(label: Option<ast::Lifetime>, expr: Option<ast::Expr>) -> ast::Expr {
let mut s = String::from("break");
if let Some(label) = label {
format_to!(s, " {}", label);
}
if let Some(expr) = expr {
format_to!(s, " {}", expr);
}
expr_from_text(&s)
}
pub fn expr_return(expr: Option<ast::Expr>) -> ast::Expr {
match expr {