Skip to content

Commit 1880be0

Browse files
committed
feat: highlighting of related return values while the cursor is on any match, if, or match arm arrow (=>)
1 parent ed737b5 commit 1880be0

File tree

6 files changed

+773
-10
lines changed

6 files changed

+773
-10
lines changed

crates/ide/src/goto_definition.rs

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ fn handle_control_flow_keywords(
299299
T![for] if token.parent().and_then(ast::ForExpr::cast).is_some() => {
300300
nav_for_break_points(sema, token)
301301
}
302+
T![match] | T![=>] | T![if] => nav_for_branches(sema, token),
302303
_ => None,
303304
}
304305
}
@@ -408,6 +409,64 @@ fn nav_for_exit_points(
408409
Some(navs)
409410
}
410411

412+
fn nav_for_branches(
413+
sema: &Semantics<'_, RootDatabase>,
414+
token: &SyntaxToken,
415+
) -> Option<Vec<NavigationTarget>> {
416+
let db = sema.db;
417+
418+
let navs = match token.kind() {
419+
T![match] => sema
420+
.descend_into_macros(token.clone())
421+
.into_iter()
422+
.filter_map(|token| {
423+
let match_expr =
424+
sema.token_ancestors_with_macros(token).find_map(ast::MatchExpr::cast)?;
425+
let file_id = sema.hir_file_for(match_expr.syntax());
426+
let focus_range = match_expr.match_token()?.text_range();
427+
let match_expr_in_file = InFile::new(file_id, match_expr.into());
428+
Some(expr_to_nav(db, match_expr_in_file, Some(focus_range)))
429+
})
430+
.flatten()
431+
.collect_vec(),
432+
433+
T![=>] => sema
434+
.descend_into_macros(token.clone())
435+
.into_iter()
436+
.filter_map(|token| {
437+
let match_arm =
438+
sema.token_ancestors_with_macros(token).find_map(ast::MatchArm::cast)?;
439+
let match_expr = sema
440+
.ancestors_with_macros(match_arm.syntax().clone())
441+
.find_map(ast::MatchExpr::cast)?;
442+
let file_id = sema.hir_file_for(match_expr.syntax());
443+
let focus_range = match_arm.fat_arrow_token()?.text_range();
444+
let match_expr_in_file = InFile::new(file_id, match_expr.into());
445+
Some(expr_to_nav(db, match_expr_in_file, Some(focus_range)))
446+
})
447+
.flatten()
448+
.collect_vec(),
449+
450+
T![if] => sema
451+
.descend_into_macros(token.clone())
452+
.into_iter()
453+
.filter_map(|token| {
454+
let if_expr =
455+
sema.token_ancestors_with_macros(token).find_map(ast::IfExpr::cast)?;
456+
let file_id = sema.hir_file_for(if_expr.syntax());
457+
let focus_range = if_expr.if_token()?.text_range();
458+
let if_expr_in_file = InFile::new(file_id, if_expr.into());
459+
Some(expr_to_nav(db, if_expr_in_file, Some(focus_range)))
460+
})
461+
.flatten()
462+
.collect_vec(),
463+
464+
_ => return Some(Vec::new()),
465+
};
466+
467+
Some(navs)
468+
}
469+
411470
pub(crate) fn find_loops(
412471
sema: &Semantics<'_, RootDatabase>,
413472
token: &SyntaxToken,
@@ -3474,6 +3533,157 @@ fn main() {
34743533
fn f1<const N: buz$0>() {}
34753534
}
34763535
}
3536+
"#,
3537+
);
3538+
}
3539+
3540+
#[test]
3541+
fn goto_def_for_match_keyword() {
3542+
check(
3543+
r#"
3544+
fn main() {
3545+
match$0 0 {
3546+
// ^^^^^
3547+
0 => {},
3548+
_ => {},
3549+
}
3550+
}
3551+
"#,
3552+
);
3553+
}
3554+
3555+
#[test]
3556+
fn goto_def_for_match_arm_fat_arrow() {
3557+
check(
3558+
r#"
3559+
fn main() {
3560+
match 0 {
3561+
0 =>$0 {},
3562+
// ^^
3563+
_ => {},
3564+
}
3565+
}
3566+
"#,
3567+
);
3568+
}
3569+
3570+
#[test]
3571+
fn goto_def_for_if_keyword() {
3572+
check(
3573+
r#"
3574+
fn main() {
3575+
if$0 true {
3576+
// ^^
3577+
()
3578+
}
3579+
}
3580+
"#,
3581+
);
3582+
}
3583+
3584+
#[test]
3585+
fn goto_def_for_match_nested_in_if() {
3586+
check(
3587+
r#"
3588+
fn main() {
3589+
if true {
3590+
match$0 0 {
3591+
// ^^^^^
3592+
0 => {},
3593+
_ => {},
3594+
}
3595+
}
3596+
}
3597+
"#,
3598+
);
3599+
}
3600+
3601+
#[test]
3602+
fn goto_def_for_multiple_match_expressions() {
3603+
check(
3604+
r#"
3605+
fn main() {
3606+
match 0 {
3607+
0 => {},
3608+
_ => {},
3609+
};
3610+
3611+
match$0 1 {
3612+
// ^^^^^
3613+
1 => {},
3614+
_ => {},
3615+
}
3616+
}
3617+
"#,
3618+
);
3619+
}
3620+
3621+
#[test]
3622+
fn goto_def_for_nested_match_expressions() {
3623+
check(
3624+
r#"
3625+
fn main() {
3626+
match 0 {
3627+
0 => match$0 1 {
3628+
// ^^^^^
3629+
1 => {},
3630+
_ => {},
3631+
},
3632+
_ => {},
3633+
}
3634+
}
3635+
"#,
3636+
);
3637+
}
3638+
3639+
#[test]
3640+
fn goto_def_for_if_else_chains() {
3641+
check(
3642+
r#"
3643+
fn main() {
3644+
if true {
3645+
()
3646+
} else if$0 false {
3647+
// ^^
3648+
()
3649+
} else {
3650+
()
3651+
}
3652+
}
3653+
"#,
3654+
);
3655+
}
3656+
3657+
#[test]
3658+
fn goto_def_for_match_with_guards() {
3659+
check(
3660+
r#"
3661+
fn main() {
3662+
match 42 {
3663+
x if x > 0 =>$0 {},
3664+
// ^^
3665+
_ => {},
3666+
}
3667+
}
3668+
"#,
3669+
);
3670+
}
3671+
3672+
#[test]
3673+
fn goto_def_for_match_with_macro_arm() {
3674+
check(
3675+
r#"
3676+
macro_rules! arm {
3677+
() => { 0 => {} };
3678+
}
3679+
3680+
fn main() {
3681+
match$0 0 {
3682+
// ^^^^^
3683+
arm!(),
3684+
_ => {},
3685+
}
3686+
}
34773687
"#,
34783688
);
34793689
}

0 commit comments

Comments
 (0)