Skip to content

Commit

Permalink
Auto merge of #15809 - Young-Flash:extract_variable_in_place, r=HKalbasi
Browse files Browse the repository at this point in the history
feat: make extract_variable assist in place

![extract_variable_without_select](https://github.com/rust-lang/rust-analyzer/assets/71162630/96be2de4-42c9-4b24-b3e1-8b3e3a2da1d9)

close #15796
  • Loading branch information
bors committed Oct 28, 2023
2 parents 46c395d + 7186a28 commit f493207
Showing 1 changed file with 151 additions and 10 deletions.
161 changes: 151 additions & 10 deletions crates/ide-assists/src/handlers/extract_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,31 @@ use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists};
// }
// ```
pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
if ctx.has_empty_selection() {
return None;
}

let node = match ctx.covering_element() {
NodeOrToken::Node(it) => it,
NodeOrToken::Token(it) if it.kind() == COMMENT => {
cov_mark::hit!(extract_var_in_comment_is_not_applicable);
let node = if ctx.has_empty_selection() {
if let Some(expr_stmt) = ctx.find_node_at_offset::<ast::ExprStmt>() {
expr_stmt.syntax().clone()
} else if let Some(expr) = ctx.find_node_at_offset::<ast::Expr>() {
expr.syntax().ancestors().find_map(valid_target_expr)?.syntax().clone()
} else {
return None;
}
NodeOrToken::Token(it) => it.parent()?,
} else {
match ctx.covering_element() {
NodeOrToken::Node(it) => it,
NodeOrToken::Token(it) if it.kind() == COMMENT => {
cov_mark::hit!(extract_var_in_comment_is_not_applicable);
return None;
}
NodeOrToken::Token(it) => it.parent()?,
}
};

let node = node.ancestors().take_while(|anc| anc.text_range() == node.text_range()).last()?;
let range = node.text_range();

let to_extract = node
.descendants()
.take_while(|it| ctx.selection_trimmed().contains_range(it.text_range()))
.take_while(|it| range.contains_range(it.text_range()))
.find_map(valid_target_expr)?;

let ty = ctx.sema.type_of_expr(&to_extract).map(TypeInfo::adjusted);
Expand Down Expand Up @@ -235,6 +244,138 @@ mod tests {

use super::*;

#[test]
fn test_extract_var_simple_without_select() {
check_assist(
extract_variable,
r#"
fn main() -> i32 {
if true {
1
} else {
2
}$0
}
"#,
r#"
fn main() -> i32 {
let $0var_name = if true {
1
} else {
2
};
var_name
}
"#,
);

check_assist(
extract_variable,
r#"
fn foo() -> i32 { 1 }
fn main() {
foo();$0
}
"#,
r#"
fn foo() -> i32 { 1 }
fn main() {
let $0foo = foo();
}
"#,
);

check_assist(
extract_variable,
r#"
fn main() {
let a = Some(2);
a.is_some();$0
}
"#,
r#"
fn main() {
let a = Some(2);
let $0is_some = a.is_some();
}
"#,
);

check_assist(
extract_variable,
r#"
fn main() {
"hello"$0;
}
"#,
r#"
fn main() {
let $0var_name = "hello";
}
"#,
);

check_assist(
extract_variable,
r#"
fn main() {
1 + 2$0;
}
"#,
r#"
fn main() {
let $0var_name = 1 + 2;
}
"#,
);

check_assist(
extract_variable,
r#"
fn main() {
match () {
() if true => 1,
_ => 2,
};$0
}
"#,
r#"
fn main() {
let $0var_name = match () {
() if true => 1,
_ => 2,
};
}
"#,
);
}

#[test]
fn test_extract_var_unit_expr_without_select_not_applicable() {
check_assist_not_applicable(
extract_variable,
r#"
fn foo() {}
fn main() {
foo()$0;
}
"#,
);

check_assist_not_applicable(
extract_variable,
r#"
fn foo() {
let mut i = 3;
if i >= 0 {
i += 1;
} else {
i -= 1;
}$0
}"#,
);
}

#[test]
fn test_extract_var_simple() {
check_assist(
Expand Down

0 comments on commit f493207

Please sign in to comment.