use new api for flip_trait_bound assist

This commit is contained in:
Aleksey Kladov 2019-10-27 16:56:53 +03:00
parent fc2fc8528b
commit 85c64ec7be
4 changed files with 58 additions and 12 deletions

View file

@ -1,21 +1,32 @@
//! Assist for swapping traits inside of a trait bound list
//!
//! E.g. `A + B` => `B + A` when the cursor is placed by the `+` inside of a
//! trait bound list
use hir::db::HirDatabase; use hir::db::HirDatabase;
use ra_syntax::{algo::non_trivia_sibling, ast::TypeBoundList, Direction, T}; use ra_syntax::{
algo::non_trivia_sibling,
ast::{self, AstNode},
Direction, T,
};
use crate::{Assist, AssistCtx, AssistId}; use crate::{Assist, AssistCtx, AssistId};
/// Flip trait bound assist. // Assist: flip_trait_bound
//
// Flips two trait bounds.
//
// ```
// fn foo<T: Clone +<|> Copy>() { }
// ```
// ->
// ```
// fn foo<T: Copy + Clone>() { }
// ```
pub(crate) fn flip_trait_bound(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { pub(crate) fn flip_trait_bound(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
// Make sure we're in a `TypeBoundList`
ctx.node_at_offset::<TypeBoundList>()?;
// We want to replicate the behavior of `flip_binexpr` by only suggesting // We want to replicate the behavior of `flip_binexpr` by only suggesting
// the assist when the cursor is on a `+` // the assist when the cursor is on a `+`
let plus = ctx.token_at_offset().find(|tkn| tkn.kind() == T![+])?; let plus = ctx.find_token_at_offset(T![+])?;
// Make sure we're in a `TypeBoundList`
if ast::TypeBoundList::cast(plus.parent()).is_none() {
return None;
}
let (before, after) = ( let (before, after) = (
non_trivia_sibling(plus.clone().into(), Direction::Prev)?, non_trivia_sibling(plus.clone().into(), Direction::Prev)?,

View file

@ -17,7 +17,17 @@ fn check(assist_id: &str, before: &str, after: &str) {
let (_assist_id, action) = crate::assists(&db, frange) let (_assist_id, action) = crate::assists(&db, frange)
.into_iter() .into_iter()
.find(|(id, _)| id.id.0 == assist_id) .find(|(id, _)| id.id.0 == assist_id)
.unwrap_or_else(|| panic!("Assist {:?} is not applicable", assist_id)); .unwrap_or_else(|| {
panic!(
"\n\nAssist is not applicable: {}\nAvailable assists: {}",
assist_id,
crate::assists(&db, frange)
.into_iter()
.map(|(id, _)| id.id.0)
.collect::<Vec<_>>()
.join(", ")
)
});
let actual = action.edit.apply(&before); let actual = action.edit.apply(&before);
assert_eq_text!(after, &actual); assert_eq_text!(after, &actual);

View file

@ -255,6 +255,19 @@ fn main() {
) )
} }
#[test]
fn doctest_flip_trait_bound() {
check(
"flip_trait_bound",
r#####"
fn foo<T: Clone +<|> Copy>() { }
"#####,
r#####"
fn foo<T: Copy + Clone>() { }
"#####,
)
}
#[test] #[test]
fn doctest_inline_local_variable() { fn doctest_inline_local_variable() {
check( check(

View file

@ -248,6 +248,18 @@ fn main() {
} }
``` ```
## `flip_trait_bound`
Flips two trait bounds.
```rust
// BEFORE
fn foo<T: Clone + Copy>() { }
// AFTER
fn foo<T: Copy + Clone>() { }
```
## `inline_local_variable` ## `inline_local_variable`
Inlines local variable. Inlines local variable.