fix(gen-doc-assist): remove lifetimes in description of new

This commit is contained in:
Côme ALLART 2022-01-05 00:23:36 +01:00
parent c5049bdcda
commit 4a5341e044

View File

@ -88,7 +88,9 @@ fn introduction_builder(ast_func: &ast::Fn, ctx: &AssistContext) -> String {
let is_new = ast_func.name()?.to_string() == "new";
match is_new && ret_ty == self_ty {
true => Some(format!("Creates a new [`{}`].", self_type(ast_func)?)),
true => {
Some(format!("Creates a new [`{}`].", lifetimes_removed(&self_type(ast_func)?)))
}
false => None,
}
} else {
@ -230,6 +232,49 @@ fn self_type(ast_func: &ast::Fn) -> Option<String> {
.map(|t| (t.to_string()))
}
/// Output the same string as the input, removing lifetimes.
///
/// Lifetimes are detected as starting with a `'` and ending with `,\s*` or before a `>`.
fn lifetimes_removed(with_lifetimes: &str) -> String {
#[derive(Debug)]
enum State {
OutOfLifetime,
AfterLifetime,
InLifetime,
}
let mut state = State::OutOfLifetime;
let mut without_lifetimes = String::new();
for c in with_lifetimes.chars() {
match state {
State::OutOfLifetime => {
if c == '\'' {
state = State::InLifetime;
} else {
without_lifetimes.push(c);
}
}
State::InLifetime => {
if c == ',' {
state = State::AfterLifetime;
} else if c == '>' {
without_lifetimes.push(c);
state = State::OutOfLifetime;
}
}
State::AfterLifetime => {
if c == '\'' {
state = State::InLifetime;
} else if !c.is_whitespace() {
without_lifetimes.push(c);
state = State::OutOfLifetime;
}
}
}
}
without_lifetimes
}
/// Heper function to get the name of the type of `self` without generic arguments
fn self_partial_type(ast_func: &ast::Fn) -> Option<String> {
let mut self_type = self_type(ast_func)?;
@ -991,6 +1036,84 @@ pub fn new(x: T) -> MyGenericStruct<T> {
);
}
#[test]
fn removes_one_lifetime_from_description() {
check_assist(
generate_documentation_template,
r#"
#[derive(Debug, PartialEq)]
pub struct MyGenericStruct<'a, T> {
pub x: &'a T,
}
impl<'a, T> MyGenericStruct<'a, T> {
pub fn new$0(x: &'a T) -> Self {
MyGenericStruct { x }
}
}
"#,
r#"
#[derive(Debug, PartialEq)]
pub struct MyGenericStruct<'a, T> {
pub x: &'a T,
}
impl<'a, T> MyGenericStruct<'a, T> {
/// Creates a new [`MyGenericStruct<T>`].
///
/// # Examples
///
/// ```
/// use test::MyGenericStruct;
///
/// assert_eq!(MyGenericStruct::new(x), );
/// ```
pub fn new(x: &'a T) -> Self {
MyGenericStruct { x }
}
}
"#,
);
}
#[test]
fn removes_all_lifetimes_from_description() {
check_assist(
generate_documentation_template,
r#"
#[derive(Debug, PartialEq)]
pub struct MyGenericStruct<'a, 'b, T> {
pub x: &'a T,
pub y: &'b T,
}
impl<'a, 'b, T> MyGenericStruct<'a, 'b, T> {
pub fn new$0(x: &'a T, y: &'b T) -> Self {
MyGenericStruct { x, y }
}
}
"#,
r#"
#[derive(Debug, PartialEq)]
pub struct MyGenericStruct<'a, 'b, T> {
pub x: &'a T,
pub y: &'b T,
}
impl<'a, 'b, T> MyGenericStruct<'a, 'b, T> {
/// Creates a new [`MyGenericStruct<T>`].
///
/// # Examples
///
/// ```
/// use test::MyGenericStruct;
///
/// assert_eq!(MyGenericStruct::new(x, y), );
/// ```
pub fn new(x: &'a T, y: &'b T) -> Self {
MyGenericStruct { x, y }
}
}
"#,
);
}
#[test]
fn detects_new_with_self() {
check_assist(