mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
feat: Add an assist to extract an expression into a static
This commit is contained in:
parent
135e71fcb3
commit
0cad614b3b
3 changed files with 682 additions and 116 deletions
|
@ -1,14 +1,12 @@
|
||||||
use hir::{HirDisplay, TypeInfo};
|
use hir::{HirDisplay, TypeInfo};
|
||||||
use ide_db::syntax_helpers::suggest_name;
|
use ide_db::{assists::GroupLabel, syntax_helpers::suggest_name};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{
|
ast::{
|
||||||
self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory,
|
self, edit::IndentLevel, edit_in_place::Indent, make, syntax_factory::SyntaxFactory,
|
||||||
AstNode,
|
AstNode,
|
||||||
},
|
},
|
||||||
syntax_editor::Position,
|
syntax_editor::Position,
|
||||||
NodeOrToken,
|
NodeOrToken, SyntaxKind, SyntaxNode, T,
|
||||||
SyntaxKind::{self},
|
|
||||||
SyntaxNode, T,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists};
|
use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists};
|
||||||
|
@ -46,6 +44,23 @@ use crate::{utils::is_body_const, AssistContext, AssistId, AssistKind, Assists};
|
||||||
// VAR_NAME * 4;
|
// VAR_NAME * 4;
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
|
|
||||||
|
// Assist: extract_static
|
||||||
|
//
|
||||||
|
// Extracts subexpression into a static.
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// fn main() {
|
||||||
|
// $0(1 + 2)$0 * 4;
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
// ->
|
||||||
|
// ```
|
||||||
|
// fn main() {
|
||||||
|
// static $0VAR_NAME: i32 = 1 + 2;
|
||||||
|
// VAR_NAME * 4;
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
||||||
let node = if ctx.has_empty_selection() {
|
let node = if ctx.has_empty_selection() {
|
||||||
if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) {
|
if let Some(t) = ctx.token_at_offset().find(|it| it.kind() == T![;]) {
|
||||||
|
@ -114,15 +129,20 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
||||||
let Some(anchor) = Anchor::from(&to_extract, kind) else {
|
let Some(anchor) = Anchor::from(&to_extract, kind) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty_string = match kind {
|
let ty_string = match kind {
|
||||||
ExtractionKind::Constant => {
|
ExtractionKind::Constant | ExtractionKind::Static => {
|
||||||
let Some(ty) = ty.clone() else {
|
let Some(ty) = ty.clone() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We can't mutably reference a const, nor can we define
|
// We can't mutably reference a const, nor can we define
|
||||||
// one using a non-const expression or one of unknown type
|
// one using a non-const expression or one of unknown type
|
||||||
if needs_mut || !is_body_const(&ctx.sema, &to_extract_no_ref) || ty.is_unknown() {
|
if needs_mut
|
||||||
|
|| !is_body_const(&ctx.sema, &to_extract_no_ref)
|
||||||
|
|| ty.is_unknown()
|
||||||
|
|| ty.is_mutable_reference()
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,92 +155,111 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
||||||
_ => "".to_owned(),
|
_ => "".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
acc.add(kind.assist_id(), kind.label(), target, |edit| {
|
acc.add_group(
|
||||||
let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract);
|
&GroupLabel("Extract into...".to_owned()),
|
||||||
|
kind.assist_id(),
|
||||||
|
kind.label(),
|
||||||
|
target,
|
||||||
|
|edit| {
|
||||||
|
let (var_name, expr_replace) = kind.get_name_and_expr(ctx, &to_extract);
|
||||||
|
|
||||||
let make = SyntaxFactory::new();
|
let make = SyntaxFactory::new();
|
||||||
let mut editor = edit.make_editor(&expr_replace);
|
let mut editor = edit.make_editor(&expr_replace);
|
||||||
|
|
||||||
let pat_name = make.name(&var_name);
|
let pat_name = make.name(&var_name);
|
||||||
let name_expr = make.expr_path(make::ext::ident_path(&var_name));
|
let name_expr = make.expr_path(make::ext::ident_path(&var_name));
|
||||||
|
|
||||||
if let Some(cap) = ctx.config.snippet_cap {
|
if let Some(cap) = ctx.config.snippet_cap {
|
||||||
let tabstop = edit.make_tabstop_before(cap);
|
let tabstop = edit.make_tabstop_before(cap);
|
||||||
editor.add_annotation(pat_name.syntax().clone(), tabstop);
|
editor.add_annotation(pat_name.syntax().clone(), tabstop);
|
||||||
}
|
|
||||||
|
|
||||||
let initializer = match ty.as_ref().filter(|_| needs_ref) {
|
|
||||||
Some(receiver_type) if receiver_type.is_mutable_reference() => {
|
|
||||||
make.expr_ref(to_extract_no_ref.clone(), true)
|
|
||||||
}
|
}
|
||||||
Some(receiver_type) if receiver_type.is_reference() => {
|
|
||||||
make.expr_ref(to_extract_no_ref.clone(), false)
|
|
||||||
}
|
|
||||||
_ => to_extract_no_ref.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_stmt: ast::Stmt = match kind {
|
let initializer = match ty.as_ref().filter(|_| needs_ref) {
|
||||||
ExtractionKind::Variable => {
|
Some(receiver_type) if receiver_type.is_mutable_reference() => {
|
||||||
let ident_pat = make.ident_pat(false, needs_mut, pat_name);
|
make.expr_ref(to_extract_no_ref.clone(), true)
|
||||||
make.let_stmt(ident_pat.into(), None, Some(initializer)).into()
|
}
|
||||||
}
|
Some(receiver_type) if receiver_type.is_reference() => {
|
||||||
ExtractionKind::Constant => {
|
make.expr_ref(to_extract_no_ref.clone(), false)
|
||||||
let ast_ty = make.ty(&ty_string);
|
}
|
||||||
ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer)).into()
|
_ => to_extract_no_ref.clone(),
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
match &anchor {
|
let new_stmt: ast::Stmt = match kind {
|
||||||
Anchor::Before(place) => {
|
ExtractionKind::Variable => {
|
||||||
let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token());
|
let ident_pat = make.ident_pat(false, needs_mut, pat_name);
|
||||||
let indent_to = IndentLevel::from_node(place);
|
make.let_stmt(ident_pat.into(), None, Some(initializer)).into()
|
||||||
|
}
|
||||||
|
ExtractionKind::Constant => {
|
||||||
|
let ast_ty = make.ty(&ty_string);
|
||||||
|
ast::Item::Const(make.item_const(None, pat_name, ast_ty, initializer))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
ExtractionKind::Static => {
|
||||||
|
let ast_ty = make.ty(&ty_string);
|
||||||
|
ast::Item::Static(make.item_static(
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
pat_name,
|
||||||
|
ast_ty,
|
||||||
|
Some(initializer),
|
||||||
|
))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Adjust ws to insert depending on if this is all inline or on separate lines
|
match &anchor {
|
||||||
let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) {
|
Anchor::Before(place) => {
|
||||||
format!("\n{indent_to}")
|
let prev_ws = place.prev_sibling_or_token().and_then(|it| it.into_token());
|
||||||
} else {
|
let indent_to = IndentLevel::from_node(place);
|
||||||
" ".to_owned()
|
|
||||||
};
|
|
||||||
|
|
||||||
editor.insert_all(
|
// Adjust ws to insert depending on if this is all inline or on separate lines
|
||||||
Position::before(place),
|
let trailing_ws = if prev_ws.is_some_and(|it| it.text().starts_with('\n')) {
|
||||||
vec![
|
format!("\n{indent_to}")
|
||||||
new_stmt.syntax().clone().into(),
|
} else {
|
||||||
make::tokens::whitespace(&trailing_ws).into(),
|
" ".to_owned()
|
||||||
],
|
};
|
||||||
);
|
|
||||||
|
|
||||||
editor.replace(expr_replace, name_expr.syntax());
|
editor.insert_all(
|
||||||
}
|
Position::before(place),
|
||||||
Anchor::Replace(stmt) => {
|
vec![
|
||||||
cov_mark::hit!(test_extract_var_expr_stmt);
|
new_stmt.syntax().clone().into(),
|
||||||
|
make::tokens::whitespace(&trailing_ws).into(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
editor.replace(stmt.syntax(), new_stmt.syntax());
|
|
||||||
}
|
|
||||||
Anchor::WrapInBlock(to_wrap) => {
|
|
||||||
let indent_to = to_wrap.indent_level();
|
|
||||||
|
|
||||||
let block = if to_wrap.syntax() == &expr_replace {
|
|
||||||
// Since `expr_replace` is the same that needs to be wrapped in a block,
|
|
||||||
// we can just directly replace it with a block
|
|
||||||
make.block_expr([new_stmt], Some(name_expr))
|
|
||||||
} else {
|
|
||||||
// `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`.
|
|
||||||
editor.replace(expr_replace, name_expr.syntax());
|
editor.replace(expr_replace, name_expr.syntax());
|
||||||
make.block_expr([new_stmt], Some(to_wrap.clone()))
|
}
|
||||||
};
|
Anchor::Replace(stmt) => {
|
||||||
|
cov_mark::hit!(test_extract_var_expr_stmt);
|
||||||
|
|
||||||
editor.replace(to_wrap.syntax(), block.syntax());
|
editor.replace(stmt.syntax(), new_stmt.syntax());
|
||||||
|
}
|
||||||
|
Anchor::WrapInBlock(to_wrap) => {
|
||||||
|
let indent_to = to_wrap.indent_level();
|
||||||
|
|
||||||
// fixup indentation of block
|
let block = if to_wrap.syntax() == &expr_replace {
|
||||||
block.indent(indent_to);
|
// Since `expr_replace` is the same that needs to be wrapped in a block,
|
||||||
|
// we can just directly replace it with a block
|
||||||
|
make.block_expr([new_stmt], Some(name_expr))
|
||||||
|
} else {
|
||||||
|
// `expr_replace` is a descendant of `to_wrap`, so we just replace it with `name_expr`.
|
||||||
|
editor.replace(expr_replace, name_expr.syntax());
|
||||||
|
make.block_expr([new_stmt], Some(to_wrap.clone()))
|
||||||
|
};
|
||||||
|
|
||||||
|
editor.replace(to_wrap.syntax(), block.syntax());
|
||||||
|
|
||||||
|
// fixup indentation of block
|
||||||
|
block.indent(indent_to);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
editor.add_mappings(make.finish_with_mappings());
|
editor.add_mappings(make.finish_with_mappings());
|
||||||
edit.add_file_edits(ctx.file_id(), editor);
|
edit.add_file_edits(ctx.file_id(), editor);
|
||||||
edit.rename();
|
edit.rename();
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
|
@ -251,15 +290,18 @@ fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> {
|
||||||
enum ExtractionKind {
|
enum ExtractionKind {
|
||||||
Variable,
|
Variable,
|
||||||
Constant,
|
Constant,
|
||||||
|
Static,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtractionKind {
|
impl ExtractionKind {
|
||||||
const ALL: &'static [ExtractionKind] = &[ExtractionKind::Variable, ExtractionKind::Constant];
|
const ALL: &'static [ExtractionKind] =
|
||||||
|
&[ExtractionKind::Variable, ExtractionKind::Constant, ExtractionKind::Static];
|
||||||
|
|
||||||
fn assist_id(&self) -> AssistId {
|
fn assist_id(&self) -> AssistId {
|
||||||
let s = match self {
|
let s = match self {
|
||||||
ExtractionKind::Variable => "extract_variable",
|
ExtractionKind::Variable => "extract_variable",
|
||||||
ExtractionKind::Constant => "extract_constant",
|
ExtractionKind::Constant => "extract_constant",
|
||||||
|
ExtractionKind::Static => "extract_static",
|
||||||
};
|
};
|
||||||
|
|
||||||
AssistId(s, AssistKind::RefactorExtract)
|
AssistId(s, AssistKind::RefactorExtract)
|
||||||
|
@ -269,6 +311,7 @@ impl ExtractionKind {
|
||||||
match self {
|
match self {
|
||||||
ExtractionKind::Variable => "Extract into variable",
|
ExtractionKind::Variable => "Extract into variable",
|
||||||
ExtractionKind::Constant => "Extract into constant",
|
ExtractionKind::Constant => "Extract into constant",
|
||||||
|
ExtractionKind::Static => "Extract into static",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +334,7 @@ impl ExtractionKind {
|
||||||
|
|
||||||
let var_name = match self {
|
let var_name = match self {
|
||||||
ExtractionKind::Variable => var_name,
|
ExtractionKind::Variable => var_name,
|
||||||
ExtractionKind::Constant => var_name.to_uppercase(),
|
ExtractionKind::Constant | ExtractionKind::Static => var_name.to_uppercase(),
|
||||||
};
|
};
|
||||||
|
|
||||||
(var_name, expr_replace)
|
(var_name, expr_replace)
|
||||||
|
@ -351,7 +394,7 @@ impl Anchor {
|
||||||
});
|
});
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
ExtractionKind::Constant if result.is_none() => {
|
ExtractionKind::Constant | ExtractionKind::Static if result.is_none() => {
|
||||||
to_extract.syntax().ancestors().find_map(|node| {
|
to_extract.syntax().ancestors().find_map(|node| {
|
||||||
let item = ast::Item::cast(node.clone())?;
|
let item = ast::Item::cast(node.clone())?;
|
||||||
let parent = item.syntax().parent()?;
|
let parent = item.syntax().parent()?;
|
||||||
|
@ -381,21 +424,6 @@ mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn now_bad() {
|
|
||||||
// unknown type
|
|
||||||
check_assist_not_applicable_by_label(
|
|
||||||
extract_variable,
|
|
||||||
r#"
|
|
||||||
fn main() {
|
|
||||||
let a = Some(2);
|
|
||||||
a.is_some();$0
|
|
||||||
}
|
|
||||||
"#,
|
|
||||||
"Extract into constant",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_simple_without_select() {
|
fn extract_var_simple_without_select() {
|
||||||
check_assist_by_label(
|
check_assist_by_label(
|
||||||
|
@ -604,7 +632,102 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_unit_expr_without_select_not_applicable() {
|
fn extract_static_simple_without_select() {
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn main() -> i32 {
|
||||||
|
if true {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
}$0
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() -> i32 {
|
||||||
|
static $0VAR_NAME: i32 = if true {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
};
|
||||||
|
VAR_NAME
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
const fn foo() -> i32 { 1 }
|
||||||
|
fn main() {
|
||||||
|
foo();$0
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
const fn foo() -> i32 { 1 }
|
||||||
|
fn main() {
|
||||||
|
static $0FOO: i32 = foo();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
"hello"$0;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
static $0VAR_NAME: &str = "hello";
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
1 + 2$0;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
static $0VAR_NAME: i32 = 1 + 2;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
match () {
|
||||||
|
() if true => 1,
|
||||||
|
_ => 2,
|
||||||
|
};$0
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
static $0VAR_NAME: i32 = match () {
|
||||||
|
() if true => 1,
|
||||||
|
_ => 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dont_extract_unit_expr_without_select() {
|
||||||
check_assist_not_applicable(
|
check_assist_not_applicable(
|
||||||
extract_variable,
|
extract_variable,
|
||||||
r#"
|
r#"
|
||||||
|
@ -664,7 +787,24 @@ fn foo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_in_comment_is_not_applicable() {
|
fn extract_static_simple() {
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
foo($01 + 1$0);
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
static $0VAR_NAME: i32 = 1 + 1;
|
||||||
|
foo(VAR_NAME);
|
||||||
|
}"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dont_extract_in_comment() {
|
||||||
cov_mark::check!(extract_var_in_comment_is_not_applicable);
|
cov_mark::check!(extract_var_in_comment_is_not_applicable);
|
||||||
check_assist_not_applicable(extract_variable, r#"fn main() { 1 + /* $0comment$0 */ 1; }"#);
|
check_assist_not_applicable(extract_variable, r#"fn main() { 1 + /* $0comment$0 */ 1; }"#);
|
||||||
}
|
}
|
||||||
|
@ -732,6 +872,38 @@ fn foo() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_static_expr_stmt() {
|
||||||
|
cov_mark::check!(test_extract_var_expr_stmt);
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
$0 1 + 1$0;
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
static $0VAR_NAME: i32 = 1 + 1;
|
||||||
|
}"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
// This is hilarious but as far as I know, it's valid
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
$0{ let x = 0; x }$0;
|
||||||
|
something_else();
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
static $0VAR_NAME: i32 = { let x = 0; x };
|
||||||
|
something_else();
|
||||||
|
}"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_part_of_expr_stmt() {
|
fn extract_var_part_of_expr_stmt() {
|
||||||
check_assist_by_label(
|
check_assist_by_label(
|
||||||
|
@ -766,6 +938,23 @@ fn foo() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_static_part_of_expr_stmt() {
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
$01$0 + 1;
|
||||||
|
}"#,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
static $0VAR_NAME: i32 = 1;
|
||||||
|
VAR_NAME + 1;
|
||||||
|
}"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_last_expr() {
|
fn extract_var_last_expr() {
|
||||||
cov_mark::check!(test_extract_var_last_expr);
|
cov_mark::check!(test_extract_var_last_expr);
|
||||||
|
@ -852,6 +1041,49 @@ const fn bar(i: i32) -> i32 {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_static_last_expr() {
|
||||||
|
cov_mark::check!(test_extract_var_last_expr);
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
bar($01 + 1$0)
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
static $0VAR_NAME: i32 = 1 + 1;
|
||||||
|
bar(VAR_NAME)
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() -> i32 {
|
||||||
|
$0bar(1 + 1)$0
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn bar(i: i32) -> i32 {
|
||||||
|
i
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
fn foo() -> i32 {
|
||||||
|
static $0BAR: i32 = bar(1 + 1);
|
||||||
|
BAR
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn bar(i: i32) -> i32 {
|
||||||
|
i
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_in_match_arm_no_block() {
|
fn extract_var_in_match_arm_no_block() {
|
||||||
cov_mark::check!(test_extract_var_in_match_arm_no_block);
|
cov_mark::check!(test_extract_var_in_match_arm_no_block);
|
||||||
|
@ -1427,6 +1659,30 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
"Extract into constant",
|
"Extract into constant",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
struct Vec;
|
||||||
|
macro_rules! vec {
|
||||||
|
() => {Vec}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let _ = $0vec![]$0;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
struct Vec;
|
||||||
|
macro_rules! vec {
|
||||||
|
() => {Vec}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
static $0VEC: Vec = vec![];
|
||||||
|
let _ = VEC;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1589,6 +1845,109 @@ fn bar() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extract_static_no_block_body() {
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
const fn foo(x: i32) -> i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
const FOO: i32 = foo($0100$0);
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
const fn foo(x: i32) -> i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
static $0X: i32 = 100;
|
||||||
|
const FOO: i32 = foo(X);
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
mod foo {
|
||||||
|
enum Foo {
|
||||||
|
Bar,
|
||||||
|
Baz = $042$0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
mod foo {
|
||||||
|
static $0VAR_NAME: isize = 42;
|
||||||
|
enum Foo {
|
||||||
|
Bar,
|
||||||
|
Baz = VAR_NAME,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
const fn foo(x: i32) -> i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Hello {
|
||||||
|
const World: i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar;
|
||||||
|
impl Hello for Bar {
|
||||||
|
const World = foo($042$0);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
const fn foo(x: i32) -> i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Hello {
|
||||||
|
const World: i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar;
|
||||||
|
impl Hello for Bar {
|
||||||
|
static $0X: i32 = 42;
|
||||||
|
const World = foo(X);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
|
||||||
|
check_assist_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
const fn foo(x: i32) -> i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() {
|
||||||
|
const BAZ: i32 = foo($042$0);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
const fn foo(x: i32) -> i32 {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() {
|
||||||
|
static $0X: i32 = 42;
|
||||||
|
const BAZ: i32 = foo(X);
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_var_mutable_reference_parameter() {
|
fn extract_var_mutable_reference_parameter() {
|
||||||
check_assist_by_label(
|
check_assist_by_label(
|
||||||
|
@ -1641,7 +2000,28 @@ impl<T> Vec<T> {
|
||||||
fn foo(s: &mut S) {
|
fn foo(s: &mut S) {
|
||||||
$0s.vec$0.push(0);
|
$0s.vec$0.push(0);
|
||||||
}"#,
|
}"#,
|
||||||
"Extract into const",
|
"Extract into constant",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dont_extract_static_mutable_reference_parameter() {
|
||||||
|
check_assist_not_applicable_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
struct S {
|
||||||
|
vec: Vec<u8>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vec<T>;
|
||||||
|
impl<T> Vec<T> {
|
||||||
|
fn push(&mut self, _:usize) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(s: &mut S) {
|
||||||
|
$0s.vec$0.push(0);
|
||||||
|
}"#,
|
||||||
|
"Extract into static",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2030,6 +2410,18 @@ fn foo() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dont_extract_static_for_mutable_borrow() {
|
||||||
|
check_assist_not_applicable_by_label(
|
||||||
|
extract_variable,
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
let v = &mut $00$0;
|
||||||
|
}"#,
|
||||||
|
"Extract into static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generates_no_ref_on_calls() {
|
fn generates_no_ref_on_calls() {
|
||||||
check_assist_by_label(
|
check_assist_by_label(
|
||||||
|
|
|
@ -362,8 +362,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
|
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Convert integer base
|
Convert integer base
|
||||||
Extract into variable
|
Extract into...
|
||||||
Extract into constant
|
|
||||||
Extract into function
|
Extract into function
|
||||||
Replace if let with match
|
Replace if let with match
|
||||||
"#]]
|
"#]]
|
||||||
|
@ -392,8 +391,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
|
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Convert integer base
|
Convert integer base
|
||||||
Extract into variable
|
Extract into...
|
||||||
Extract into constant
|
|
||||||
Extract into function
|
Extract into function
|
||||||
Replace if let with match
|
Replace if let with match
|
||||||
"#]]
|
"#]]
|
||||||
|
@ -407,8 +405,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
let expected = labels(&assists);
|
let expected = labels(&assists);
|
||||||
|
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Extract into variable
|
Extract into...
|
||||||
Extract into constant
|
|
||||||
Extract into function
|
Extract into function
|
||||||
"#]]
|
"#]]
|
||||||
.assert_eq(&expected);
|
.assert_eq(&expected);
|
||||||
|
@ -443,7 +440,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
|
|
||||||
{
|
{
|
||||||
let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into());
|
let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange.into());
|
||||||
assert_eq!(3, assists.len());
|
assert_eq!(4, assists.len());
|
||||||
let mut assists = assists.into_iter();
|
let mut assists = assists.into_iter();
|
||||||
|
|
||||||
let extract_into_variable_assist = assists.next().unwrap();
|
let extract_into_variable_assist = assists.next().unwrap();
|
||||||
|
@ -454,7 +451,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into variable",
|
label: "Extract into variable",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: None,
|
source_change: None,
|
||||||
command: None,
|
command: None,
|
||||||
|
@ -470,7 +471,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into constant",
|
label: "Extract into constant",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: None,
|
source_change: None,
|
||||||
command: None,
|
command: None,
|
||||||
|
@ -478,6 +483,26 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
"#]]
|
"#]]
|
||||||
.assert_debug_eq(&extract_into_constant_assist);
|
.assert_debug_eq(&extract_into_constant_assist);
|
||||||
|
|
||||||
|
let extract_into_static_assist = assists.next().unwrap();
|
||||||
|
expect![[r#"
|
||||||
|
Assist {
|
||||||
|
id: AssistId(
|
||||||
|
"extract_static",
|
||||||
|
RefactorExtract,
|
||||||
|
),
|
||||||
|
label: "Extract into static",
|
||||||
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
target: 59..60,
|
||||||
|
source_change: None,
|
||||||
|
command: None,
|
||||||
|
}
|
||||||
|
"#]]
|
||||||
|
.assert_debug_eq(&extract_into_static_assist);
|
||||||
|
|
||||||
let extract_into_function_assist = assists.next().unwrap();
|
let extract_into_function_assist = assists.next().unwrap();
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Assist {
|
Assist {
|
||||||
|
@ -505,7 +530,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
}),
|
}),
|
||||||
frange.into(),
|
frange.into(),
|
||||||
);
|
);
|
||||||
assert_eq!(3, assists.len());
|
assert_eq!(4, assists.len());
|
||||||
let mut assists = assists.into_iter();
|
let mut assists = assists.into_iter();
|
||||||
|
|
||||||
let extract_into_variable_assist = assists.next().unwrap();
|
let extract_into_variable_assist = assists.next().unwrap();
|
||||||
|
@ -516,7 +541,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into variable",
|
label: "Extract into variable",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: None,
|
source_change: None,
|
||||||
command: None,
|
command: None,
|
||||||
|
@ -532,7 +561,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into constant",
|
label: "Extract into constant",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: None,
|
source_change: None,
|
||||||
command: None,
|
command: None,
|
||||||
|
@ -540,6 +573,26 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
"#]]
|
"#]]
|
||||||
.assert_debug_eq(&extract_into_constant_assist);
|
.assert_debug_eq(&extract_into_constant_assist);
|
||||||
|
|
||||||
|
let extract_into_static_assist = assists.next().unwrap();
|
||||||
|
expect![[r#"
|
||||||
|
Assist {
|
||||||
|
id: AssistId(
|
||||||
|
"extract_static",
|
||||||
|
RefactorExtract,
|
||||||
|
),
|
||||||
|
label: "Extract into static",
|
||||||
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
target: 59..60,
|
||||||
|
source_change: None,
|
||||||
|
command: None,
|
||||||
|
}
|
||||||
|
"#]]
|
||||||
|
.assert_debug_eq(&extract_into_static_assist);
|
||||||
|
|
||||||
let extract_into_function_assist = assists.next().unwrap();
|
let extract_into_function_assist = assists.next().unwrap();
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Assist {
|
Assist {
|
||||||
|
@ -567,7 +620,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
}),
|
}),
|
||||||
frange.into(),
|
frange.into(),
|
||||||
);
|
);
|
||||||
assert_eq!(3, assists.len());
|
assert_eq!(4, assists.len());
|
||||||
let mut assists = assists.into_iter();
|
let mut assists = assists.into_iter();
|
||||||
|
|
||||||
let extract_into_variable_assist = assists.next().unwrap();
|
let extract_into_variable_assist = assists.next().unwrap();
|
||||||
|
@ -578,7 +631,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into variable",
|
label: "Extract into variable",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: Some(
|
source_change: Some(
|
||||||
SourceChange {
|
SourceChange {
|
||||||
|
@ -637,7 +694,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into constant",
|
label: "Extract into constant",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: None,
|
source_change: None,
|
||||||
command: None,
|
command: None,
|
||||||
|
@ -645,6 +706,26 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
"#]]
|
"#]]
|
||||||
.assert_debug_eq(&extract_into_constant_assist);
|
.assert_debug_eq(&extract_into_constant_assist);
|
||||||
|
|
||||||
|
let extract_into_static_assist = assists.next().unwrap();
|
||||||
|
expect![[r#"
|
||||||
|
Assist {
|
||||||
|
id: AssistId(
|
||||||
|
"extract_static",
|
||||||
|
RefactorExtract,
|
||||||
|
),
|
||||||
|
label: "Extract into static",
|
||||||
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
target: 59..60,
|
||||||
|
source_change: None,
|
||||||
|
command: None,
|
||||||
|
}
|
||||||
|
"#]]
|
||||||
|
.assert_debug_eq(&extract_into_static_assist);
|
||||||
|
|
||||||
let extract_into_function_assist = assists.next().unwrap();
|
let extract_into_function_assist = assists.next().unwrap();
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Assist {
|
Assist {
|
||||||
|
@ -664,7 +745,7 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
|
|
||||||
{
|
{
|
||||||
let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into());
|
let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange.into());
|
||||||
assert_eq!(3, assists.len());
|
assert_eq!(4, assists.len());
|
||||||
let mut assists = assists.into_iter();
|
let mut assists = assists.into_iter();
|
||||||
|
|
||||||
let extract_into_variable_assist = assists.next().unwrap();
|
let extract_into_variable_assist = assists.next().unwrap();
|
||||||
|
@ -675,7 +756,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into variable",
|
label: "Extract into variable",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: Some(
|
source_change: Some(
|
||||||
SourceChange {
|
SourceChange {
|
||||||
|
@ -734,7 +819,11 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
RefactorExtract,
|
RefactorExtract,
|
||||||
),
|
),
|
||||||
label: "Extract into constant",
|
label: "Extract into constant",
|
||||||
group: None,
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
target: 59..60,
|
target: 59..60,
|
||||||
source_change: Some(
|
source_change: Some(
|
||||||
SourceChange {
|
SourceChange {
|
||||||
|
@ -789,6 +878,73 @@ pub fn test_some_range(a: int) -> bool {
|
||||||
"#]]
|
"#]]
|
||||||
.assert_debug_eq(&extract_into_constant_assist);
|
.assert_debug_eq(&extract_into_constant_assist);
|
||||||
|
|
||||||
|
let extract_into_static_assist = assists.next().unwrap();
|
||||||
|
expect![[r#"
|
||||||
|
Assist {
|
||||||
|
id: AssistId(
|
||||||
|
"extract_static",
|
||||||
|
RefactorExtract,
|
||||||
|
),
|
||||||
|
label: "Extract into static",
|
||||||
|
group: Some(
|
||||||
|
GroupLabel(
|
||||||
|
"Extract into...",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
target: 59..60,
|
||||||
|
source_change: Some(
|
||||||
|
SourceChange {
|
||||||
|
source_file_edits: {
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
): (
|
||||||
|
TextEdit {
|
||||||
|
indels: [
|
||||||
|
Indel {
|
||||||
|
insert: "static",
|
||||||
|
delete: 45..47,
|
||||||
|
},
|
||||||
|
Indel {
|
||||||
|
insert: "VAR_NAME:",
|
||||||
|
delete: 48..60,
|
||||||
|
},
|
||||||
|
Indel {
|
||||||
|
insert: "i32",
|
||||||
|
delete: 61..81,
|
||||||
|
},
|
||||||
|
Indel {
|
||||||
|
insert: "=",
|
||||||
|
delete: 82..86,
|
||||||
|
},
|
||||||
|
Indel {
|
||||||
|
insert: "5;\n if let 2..6 = VAR_NAME {\n true\n } else {\n false\n }",
|
||||||
|
delete: 87..108,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Some(
|
||||||
|
SnippetEdit(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
52..52,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
file_system_edits: [],
|
||||||
|
is_snippet: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
command: Some(
|
||||||
|
Rename,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"#]]
|
||||||
|
.assert_debug_eq(&extract_into_static_assist);
|
||||||
|
|
||||||
let extract_into_function_assist = assists.next().unwrap();
|
let extract_into_function_assist = assists.next().unwrap();
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
Assist {
|
Assist {
|
||||||
|
|
|
@ -1024,6 +1024,24 @@ fn bar(name: i32) -> i32 {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn doctest_extract_static() {
|
||||||
|
check_doc_test(
|
||||||
|
"extract_static",
|
||||||
|
r#####"
|
||||||
|
fn main() {
|
||||||
|
$0(1 + 2)$0 * 4;
|
||||||
|
}
|
||||||
|
"#####,
|
||||||
|
r#####"
|
||||||
|
fn main() {
|
||||||
|
static $0VAR_NAME: i32 = 1 + 2;
|
||||||
|
VAR_NAME * 4;
|
||||||
|
}
|
||||||
|
"#####,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn doctest_extract_struct_from_enum_variant() {
|
fn doctest_extract_struct_from_enum_variant() {
|
||||||
check_doc_test(
|
check_doc_test(
|
||||||
|
|
Loading…
Reference in a new issue