From 1967884d6836219ee78a754ca5c66ac781351559 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 8 Jan 2019 22:17:36 +0300 Subject: rename ra_editor -> ra_ide_api_light --- crates/ra_ide_api_light/src/assists/add_derive.rs | 84 +++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 crates/ra_ide_api_light/src/assists/add_derive.rs (limited to 'crates/ra_ide_api_light/src/assists/add_derive.rs') diff --git a/crates/ra_ide_api_light/src/assists/add_derive.rs b/crates/ra_ide_api_light/src/assists/add_derive.rs new file mode 100644 index 000000000..6e964d011 --- /dev/null +++ b/crates/ra_ide_api_light/src/assists/add_derive.rs @@ -0,0 +1,84 @@ +use ra_syntax::{ + ast::{self, AstNode, AttrsOwner}, + SyntaxKind::{WHITESPACE, COMMENT}, + TextUnit, +}; + +use crate::assists::{AssistCtx, Assist}; + +pub fn add_derive(ctx: AssistCtx) -> Option { + let nominal = ctx.node_at_offset::()?; + let node_start = derive_insertion_offset(nominal)?; + ctx.build("add `#[derive]`", |edit| { + let derive_attr = nominal + .attrs() + .filter_map(|x| x.as_call()) + .filter(|(name, _arg)| name == "derive") + .map(|(_name, arg)| arg) + .next(); + let offset = match derive_attr { + None => { + edit.insert(node_start, "#[derive()]\n"); + node_start + TextUnit::of_str("#[derive(") + } + Some(tt) => tt.syntax().range().end() - TextUnit::of_char(')'), + }; + edit.set_cursor(offset) + }) +} + +// Insert `derive` after doc comments. +fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option { + let non_ws_child = nominal + .syntax() + .children() + .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; + Some(non_ws_child.range().start()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::assists::check_assist; + + #[test] + fn add_derive_new() { + check_assist( + add_derive, + "struct Foo { a: i32, <|>}", + "#[derive(<|>)]\nstruct Foo { a: i32, }", + ); + check_assist( + add_derive, + "struct Foo { <|> a: i32, }", + "#[derive(<|>)]\nstruct Foo { a: i32, }", + ); + } + + #[test] + fn add_derive_existing() { + check_assist( + add_derive, + "#[derive(Clone)]\nstruct Foo { a: i32<|>, }", + "#[derive(Clone<|>)]\nstruct Foo { a: i32, }", + ); + } + + #[test] + fn add_derive_new_with_doc_comment() { + check_assist( + add_derive, + " +/// `Foo` is a pretty important struct. +/// It does stuff. +struct Foo { a: i32<|>, } + ", + " +/// `Foo` is a pretty important struct. +/// It does stuff. +#[derive(<|>)] +struct Foo { a: i32, } + ", + ); + } +} -- cgit v1.2.3