From e4756cb4f6e66097638b9d101589358976be2ba8 Mon Sep 17 00:00:00 2001 From: Chetan Khilosiya Date: Tue, 23 Feb 2021 00:17:48 +0530 Subject: 7526: Rename crate assists to ide_assists. --- .../ide_assists/src/handlers/flip_trait_bound.rs | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 crates/ide_assists/src/handlers/flip_trait_bound.rs (limited to 'crates/ide_assists/src/handlers/flip_trait_bound.rs') diff --git a/crates/ide_assists/src/handlers/flip_trait_bound.rs b/crates/ide_assists/src/handlers/flip_trait_bound.rs new file mode 100644 index 000000000..d419d263e --- /dev/null +++ b/crates/ide_assists/src/handlers/flip_trait_bound.rs @@ -0,0 +1,121 @@ +use syntax::{ + algo::non_trivia_sibling, + ast::{self, AstNode}, + Direction, T, +}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: flip_trait_bound +// +// Flips two trait bounds. +// +// ``` +// fn foo() { } +// ``` +// -> +// ``` +// fn foo() { } +// ``` +pub(crate) fn flip_trait_bound(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { + // We want to replicate the behavior of `flip_binexpr` by only suggesting + // the assist when the cursor is on a `+` + let plus = ctx.find_token_syntax_at_offset(T![+])?; + + // Make sure we're in a `TypeBoundList` + if ast::TypeBoundList::cast(plus.parent()).is_none() { + return None; + } + + let (before, after) = ( + non_trivia_sibling(plus.clone().into(), Direction::Prev)?, + non_trivia_sibling(plus.clone().into(), Direction::Next)?, + ); + + let target = plus.text_range(); + acc.add( + AssistId("flip_trait_bound", AssistKind::RefactorRewrite), + "Flip trait bounds", + target, + |edit| { + edit.replace(before.text_range(), after.to_string()); + edit.replace(after.text_range(), before.to_string()); + }, + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; + + #[test] + fn flip_trait_bound_assist_available() { + check_assist_target(flip_trait_bound, "struct S where T: A $0+ B + C { }", "+") + } + + #[test] + fn flip_trait_bound_not_applicable_for_single_trait_bound() { + check_assist_not_applicable(flip_trait_bound, "struct S where T: $0A { }") + } + + #[test] + fn flip_trait_bound_works_for_struct() { + check_assist( + flip_trait_bound, + "struct S where T: A $0+ B { }", + "struct S where T: B + A { }", + ) + } + + #[test] + fn flip_trait_bound_works_for_trait_impl() { + check_assist( + flip_trait_bound, + "impl X for S where T: A +$0 B { }", + "impl X for S where T: B + A { }", + ) + } + + #[test] + fn flip_trait_bound_works_for_fn() { + check_assist(flip_trait_bound, "fn f(t: T) { }", "fn f(t: T) { }") + } + + #[test] + fn flip_trait_bound_works_for_fn_where_clause() { + check_assist( + flip_trait_bound, + "fn f(t: T) where T: A +$0 B { }", + "fn f(t: T) where T: B + A { }", + ) + } + + #[test] + fn flip_trait_bound_works_for_lifetime() { + check_assist( + flip_trait_bound, + "fn f(t: T) where T: A $0+ 'static { }", + "fn f(t: T) where T: 'static + A { }", + ) + } + + #[test] + fn flip_trait_bound_works_for_complex_bounds() { + check_assist( + flip_trait_bound, + "struct S where T: A $0+ b_mod::B + C { }", + "struct S where T: b_mod::B + A + C { }", + ) + } + + #[test] + fn flip_trait_bound_works_for_long_bounds() { + check_assist( + flip_trait_bound, + "struct S where T: A + B + C + D + E + F +$0 G + H + I + J { }", + "struct S where T: A + B + C + D + E + G + F + H + I + J { }", + ) + } +} -- cgit v1.2.3