From c9598a4cbfdf4b0d0d993043dca48c1615b63145 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 29 May 2021 17:19:49 +0200 Subject: [PATCH] Add some lint completion tests --- .../src/completions/attribute.rs | 26 ++++++------- .../src/completions/attribute/derive.rs | 38 +++++++++++-------- .../src/completions/attribute/lint.rs | 33 ++++++++++++++++ 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 610fec65a74..13d5b90c99e 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs @@ -3,8 +3,6 @@ //! This module uses a bit of static metadata to provide completions //! for built-in attributes. -use std::mem; - use once_cell::sync::Lazy; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ast, AstNode, NodeOrToken, SyntaxKind, T}; @@ -272,27 +270,27 @@ macro_rules! attrs { fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Option> { let (l_paren, r_paren) = derive_input.l_paren_token().zip(derive_input.r_paren_token())?; let mut input_derives = FxHashSet::default(); - let mut current_derive = String::new(); - for token in derive_input + let mut tokens = derive_input .syntax() .children_with_tokens() .filter_map(NodeOrToken::into_token) .skip_while(|token| token != &l_paren) .skip(1) .take_while(|token| token != &r_paren) - { - if token.kind() == T![,] { - if !current_derive.is_empty() { - input_derives.insert(mem::take(&mut current_derive)); - } - } else { - current_derive.push_str(token.text().trim()); + .peekable(); + let mut input = String::new(); + while tokens.peek().is_some() { + for token in tokens.by_ref().take_while(|t| t.kind() != T![,]) { + input.push_str(token.text()); } + + if !input.is_empty() { + input_derives.insert(input.trim().to_owned()); + } + + input.clear(); } - if !current_derive.is_empty() { - input_derives.insert(current_derive); - } Some(input_derives) } diff --git a/crates/ide_completion/src/completions/attribute/derive.rs b/crates/ide_completion/src/completions/attribute/derive.rs index 7b0a778a226..634c0cb00d9 100644 --- a/crates/ide_completion/src/completions/attribute/derive.rs +++ b/crates/ide_completion/src/completions/attribute/derive.rs @@ -45,6 +45,7 @@ pub(super) fn complete_derive( } } } + fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet { let mut result = FxHashSet::default(); ctx.scope.process_all_names(&mut |name, scope_def| { @@ -89,12 +90,14 @@ fn check(ra_fixture: &str, expect: Expect) { } #[test] - fn empty_derive_completion() { + fn no_completion_for_incorrect_derive() { + check(r#"#[derive{$0)] struct Test;"#, expect![[]]) + } + + #[test] + fn empty_derive() { check( - r#" -#[derive($0)] -struct Test {} - "#, + r#"#[derive($0)] struct Test;"#, expect![[r#" at Clone at Clone, Copy @@ -110,23 +113,26 @@ struct Test {} } #[test] - fn no_completion_for_incorrect_derive() { + fn derive_with_input() { check( - r#" -#[derive{$0)] -struct Test {} -"#, - expect![[r#""#]], + r#"#[derive(serde::Serialize, PartialEq, $0)] struct Test;"#, + expect![[r#" + at Clone + at Clone, Copy + at Debug + at Default + at Hash + at Eq + at PartialOrd + at Eq, PartialOrd, Ord + "#]], ) } #[test] - fn derive_with_input_completion() { + fn derive_with_input2() { check( - r#" -#[derive(serde::Serialize, PartialEq, $0)] -struct Test {} -"#, + r#"#[derive($0 serde::Serialize, PartialEq)] struct Test;"#, expect![[r#" at Clone at Clone, Copy diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs index 115c6cfe0cb..403630dce46 100644 --- a/crates/ide_completion/src/completions/attribute/lint.rs +++ b/crates/ide_completion/src/completions/attribute/lint.rs @@ -152,3 +152,36 @@ pub(crate) struct LintCompletion { LintCompletion { label: "unconditional_panic", description: r#"operation will cause a panic at runtime"# }, LintCompletion { label: "unknown_crate_types", description: r#"unknown crate type found in `#[crate_type]` directive"# }, ]; + +#[cfg(test)] +mod tests { + + use crate::test_utils::check_edit; + + #[test] + fn check_empty() { + check_edit( + "deprecated", + r#"#[allow($0)] struct Test;"#, + r#"#[allow(deprecated)] struct Test;"#, + ) + } + + #[test] + fn check_with_existing() { + check_edit( + "deprecated", + r#"#[allow(keyword_idents, $0)] struct Test;"#, + r#"#[allow(keyword_idents, deprecated)] struct Test;"#, + ) + } + + #[test] + fn check_qualified() { + check_edit( + "deprecated", + r#"#[allow(keyword_idents, $0)] struct Test;"#, + r#"#[allow(keyword_idents, deprecated)] struct Test;"#, + ) + } +}