From 561b4b11ff1d87ea1ff2477dcba6ae1f396573a3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 7 Feb 2020 15:53:31 +0100 Subject: Name assist handlers --- crates/ra_assists/src/assists/add_custom_impl.rs | 209 ----------------------- 1 file changed, 209 deletions(-) delete mode 100644 crates/ra_assists/src/assists/add_custom_impl.rs (limited to 'crates/ra_assists/src/assists/add_custom_impl.rs') diff --git a/crates/ra_assists/src/assists/add_custom_impl.rs b/crates/ra_assists/src/assists/add_custom_impl.rs deleted file mode 100644 index 7fdd816bf..000000000 --- a/crates/ra_assists/src/assists/add_custom_impl.rs +++ /dev/null @@ -1,209 +0,0 @@ -//! FIXME: write short doc here - -use crate::{Assist, AssistCtx, AssistId}; - -use join_to_string::join; -use ra_syntax::{ - ast::{self, AstNode}, - Direction, SmolStr, - SyntaxKind::{IDENT, WHITESPACE}, - TextRange, TextUnit, -}; - -const DERIVE_TRAIT: &str = "derive"; - -// Assist: add_custom_impl -// -// Adds impl block for derived trait. -// -// ``` -// #[derive(Deb<|>ug, Display)] -// struct S; -// ``` -// -> -// ``` -// #[derive(Display)] -// struct S; -// -// impl Debug for S { -// -// } -// ``` -pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option { - let input = ctx.find_node_at_offset::()?; - let attr = input.syntax().parent().and_then(ast::Attr::cast)?; - - let attr_name = attr - .syntax() - .descendants_with_tokens() - .filter(|t| t.kind() == IDENT) - .find_map(|i| i.into_token()) - .filter(|t| *t.text() == DERIVE_TRAIT)? - .text() - .clone(); - - let trait_token = - ctx.token_at_offset().filter(|t| t.kind() == IDENT && *t.text() != attr_name).next()?; - - let annotated = attr.syntax().siblings(Direction::Next).find_map(|s| ast::Name::cast(s))?; - let annotated_name = annotated.syntax().text().to_string(); - let start_offset = annotated.syntax().parent()?.text_range().end(); - - let label = - format!("Add custom impl '{}' for '{}'", trait_token.text().as_str(), annotated_name); - - ctx.add_assist(AssistId("add_custom_impl"), label, |edit| { - edit.target(attr.syntax().text_range()); - - let new_attr_input = input - .syntax() - .descendants_with_tokens() - .filter(|t| t.kind() == IDENT) - .filter_map(|t| t.into_token().map(|t| t.text().clone())) - .filter(|t| t != trait_token.text()) - .collect::>(); - let has_more_derives = new_attr_input.len() > 0; - let new_attr_input = - join(new_attr_input.iter()).separator(", ").surround_with("(", ")").to_string(); - let new_attr_input_len = new_attr_input.len(); - - let mut buf = String::new(); - buf.push_str("\n\nimpl "); - buf.push_str(trait_token.text().as_str()); - buf.push_str(" for "); - buf.push_str(annotated_name.as_str()); - buf.push_str(" {\n"); - - let cursor_delta = if has_more_derives { - edit.replace(input.syntax().text_range(), new_attr_input); - input.syntax().text_range().len() - TextUnit::from_usize(new_attr_input_len) - } else { - let attr_range = attr.syntax().text_range(); - edit.delete(attr_range); - - let line_break_range = attr - .syntax() - .next_sibling_or_token() - .filter(|t| t.kind() == WHITESPACE) - .map(|t| t.text_range()) - .unwrap_or(TextRange::from_to(TextUnit::from(0), TextUnit::from(0))); - edit.delete(line_break_range); - - attr_range.len() + line_break_range.len() - }; - - edit.set_cursor(start_offset + TextUnit::of_str(&buf) - cursor_delta); - buf.push_str("\n}"); - edit.insert(start_offset, buf); - }) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::helpers::{check_assist, check_assist_not_applicable}; - - #[test] - fn add_custom_impl_for_unique_input() { - check_assist( - add_custom_impl, - " -#[derive(Debu<|>g)] -struct Foo { - bar: String, -} - ", - " -struct Foo { - bar: String, -} - -impl Debug for Foo { -<|> -} - ", - ) - } - - #[test] - fn add_custom_impl_for_with_visibility_modifier() { - check_assist( - add_custom_impl, - " -#[derive(Debug<|>)] -pub struct Foo { - bar: String, -} - ", - " -pub struct Foo { - bar: String, -} - -impl Debug for Foo { -<|> -} - ", - ) - } - - #[test] - fn add_custom_impl_when_multiple_inputs() { - check_assist( - add_custom_impl, - " -#[derive(Display, Debug<|>, Serialize)] -struct Foo {} - ", - " -#[derive(Display, Serialize)] -struct Foo {} - -impl Debug for Foo { -<|> -} - ", - ) - } - - #[test] - fn test_ignore_derive_macro_without_input() { - check_assist_not_applicable( - add_custom_impl, - " -#[derive(<|>)] -struct Foo {} - ", - ) - } - - #[test] - fn test_ignore_if_cursor_on_param() { - check_assist_not_applicable( - add_custom_impl, - " -#[derive<|>(Debug)] -struct Foo {} - ", - ); - - check_assist_not_applicable( - add_custom_impl, - " -#[derive(Debug)<|>] -struct Foo {} - ", - ) - } - - #[test] - fn test_ignore_if_not_derive() { - check_assist_not_applicable( - add_custom_impl, - " -#[allow(non_camel_<|>case_types)] -struct Foo {} - ", - ) - } -} -- cgit v1.2.3