X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Fide_assists%2Fsrc%2Fhandlers%2Fextract_function.rs;h=719f22053cce2c85864524adadd8efda60108d57;hb=09a78caca403f1b4be8711d00519094896928e58;hp=8779d8bd1a5028bfc10df228204be16bdc4cd45d;hpb=3ee531afd8fbc4542ebf3b7e616564ea4a5f32a4;p=rust.git diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 8779d8bd1a5..719f22053cc 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs @@ -16,11 +16,9 @@ edit::{AstNodeEdit, IndentLevel}, AstNode, }, - SyntaxElement, SyntaxKind::{self, BLOCK_EXPR, BREAK_EXPR, COMMENT, PATH_EXPR, RETURN_EXPR}, SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T, }; -use test_utils::mark; use crate::{ assist_context::{AssistContext, Assists}, @@ -59,11 +57,14 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option let node = ctx.covering_element(); if node.kind() == COMMENT { - mark::hit!(extract_function_in_comment_is_not_applicable); + cov_mark::hit!(extract_function_in_comment_is_not_applicable); return None; } - let node = element_to_node(node); + let node = match node { + syntax::NodeOrToken::Node(n) => n, + syntax::NodeOrToken::Token(t) => t.parent()?, + }; let body = extraction_target(&node, ctx.frange.range)?; @@ -197,14 +198,14 @@ fn external_control_flow(ctx: &AssistContext, body: &FunctionBody) -> Option return None, }, (Some(_), _, _, _) => { - mark::hit!(external_control_flow_try_and_bc); + cov_mark::hit!(external_control_flow_try_and_bc); return None; } (None, Some(r), None, None) => match r.expr() { @@ -212,11 +213,11 @@ fn external_control_flow(ctx: &AssistContext, body: &FunctionBody) -> Option Some(FlowKind::Return), }, (None, Some(_), _, _) => { - mark::hit!(external_control_flow_return_and_bc); + cov_mark::hit!(external_control_flow_return_and_bc); return None; } (None, None, Some(_), Some(_)) => { - mark::hit!(external_control_flow_break_and_continue); + cov_mark::hit!(external_control_flow_break_and_continue); return None; } (None, None, Some(b), None) => match b.expr() { @@ -561,14 +562,6 @@ fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset { } } -/// node or token's parent -fn element_to_node(node: SyntaxElement) -> SyntaxNode { - match node { - syntax::NodeOrToken::Node(n) => n, - syntax::NodeOrToken::Token(t) => t.parent(), - } -} - /// Try to guess what user wants to extract /// /// We have basically have two cases: @@ -736,6 +729,14 @@ fn reference_is_exclusive( /// checks if this expr requires `&mut` access, recurses on field access fn expr_require_exclusive_access(ctx: &AssistContext, expr: &ast::Expr) -> Option { + match expr { + ast::Expr::MacroCall(_) => { + // FIXME: expand macro and check output for mutable usages of the variable? + return None; + } + _ => (), + } + let parent = expr.syntax().parent()?; if let Some(bin_expr) = ast::BinExpr::cast(parent.clone()) { @@ -794,7 +795,7 @@ fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset { } } -/// find relevant `ast::PathExpr` for reference +/// find relevant `ast::Expr` for reference /// /// # Preconditions /// @@ -811,7 +812,11 @@ fn path_element_of_reference( stdx::never!(false, "cannot find path parent of variable usage: {:?}", token); None })?; - stdx::always!(matches!(path, ast::Expr::PathExpr(_))); + stdx::always!( + matches!(path, ast::Expr::PathExpr(_) | ast::Expr::MacroCall(_)), + "unexpected expression type for variable usage: {:?}", + path + ); Some(path) } @@ -1247,7 +1252,7 @@ fn make_body( }) } FlowHandler::If { .. } => { - let lit_false = ast::Literal::cast(make::tokens::literal("false").parent()).unwrap(); + let lit_false = make::expr_literal("false"); with_tail_expr(block, lit_false.into()) } FlowHandler::IfOption { .. } => { @@ -1421,9 +1426,7 @@ fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) -> S fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option) -> Option { let value = match handler { FlowHandler::None | FlowHandler::Try { .. } => return None, - FlowHandler::If { .. } => { - ast::Literal::cast(make::tokens::literal("true").parent()).unwrap().into() - } + FlowHandler::If { .. } => make::expr_literal("true").into(), FlowHandler::IfOption { .. } => { let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new())); let args = make::arg_list(iter::once(expr)); @@ -1837,7 +1840,7 @@ fn $0fun_name(n: u32) -> u32 { #[test] fn in_comment_is_not_applicable() { - mark::check!(extract_function_in_comment_is_not_applicable); + cov_mark::check!(extract_function_in_comment_is_not_applicable); check_assist_not_applicable(extract_function, r"fn main() { 1 + /* $0comment$0 */ 1; }"); } @@ -2822,7 +2825,7 @@ fn $0fun_name(n: i32) -> Result { #[test] fn break_and_continue() { - mark::check!(external_control_flow_break_and_continue); + cov_mark::check!(external_control_flow_break_and_continue); check_assist_not_applicable( extract_function, r##" @@ -2842,7 +2845,7 @@ fn foo() { #[test] fn return_and_break() { - mark::check!(external_control_flow_return_and_bc); + cov_mark::check!(external_control_flow_return_and_bc); check_assist_not_applicable( extract_function, r##" @@ -3341,7 +3344,7 @@ fn $0fun_name() -> Result { #[test] fn try_and_break() { - mark::check!(external_control_flow_try_and_bc); + cov_mark::check!(external_control_flow_try_and_bc); check_assist_not_applicable( extract_function, r##" @@ -3363,7 +3366,7 @@ fn foo() -> Option<()> { #[test] fn try_and_return_ok() { - mark::check!(external_control_flow_try_and_return_non_err); + cov_mark::check!(external_control_flow_try_and_return_non_err); check_assist_not_applicable( extract_function, r##" @@ -3381,4 +3384,36 @@ fn foo() -> Result<(), i64> { }"##, ); } + + #[test] + fn param_usage_in_macro() { + check_assist( + extract_function, + r" +macro_rules! m { + ($val:expr) => { $val }; +} + +fn foo() { + let n = 1; + $0let k = n * m!(n);$0 + let m = k + 1; +}", + r" +macro_rules! m { + ($val:expr) => { $val }; +} + +fn foo() { + let n = 1; + let k = fun_name(n); + let m = k + 1; +} + +fn $0fun_name(n: i32) -> i32 { + let k = n * m!(n); + k +}", + ); + } }