9048: Add some lint completion tests r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-05-29 15:33:57 +00:00 committed by GitHub
commit 3fa3343e47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 30 deletions

View file

@ -3,8 +3,6 @@
//! This module uses a bit of static metadata to provide completions //! This module uses a bit of static metadata to provide completions
//! for built-in attributes. //! for built-in attributes.
use std::mem;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use syntax::{ast, AstNode, NodeOrToken, SyntaxKind, T}; use syntax::{ast, AstNode, NodeOrToken, SyntaxKind, T};
@ -272,27 +270,27 @@ const ATTRIBUTES: &[AttrCompletion] = &[
fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Option<FxHashSet<String>> { fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Option<FxHashSet<String>> {
let (l_paren, r_paren) = derive_input.l_paren_token().zip(derive_input.r_paren_token())?; let (l_paren, r_paren) = derive_input.l_paren_token().zip(derive_input.r_paren_token())?;
let mut input_derives = FxHashSet::default(); let mut input_derives = FxHashSet::default();
let mut current_derive = String::new(); let mut tokens = derive_input
for token in derive_input
.syntax() .syntax()
.children_with_tokens() .children_with_tokens()
.filter_map(NodeOrToken::into_token) .filter_map(NodeOrToken::into_token)
.skip_while(|token| token != &l_paren) .skip_while(|token| token != &l_paren)
.skip(1) .skip(1)
.take_while(|token| token != &r_paren) .take_while(|token| token != &r_paren)
{ .peekable();
if token.kind() == T![,] { let mut input = String::new();
if !current_derive.is_empty() { while tokens.peek().is_some() {
input_derives.insert(mem::take(&mut current_derive)); for token in tokens.by_ref().take_while(|t| t.kind() != T![,]) {
} input.push_str(token.text());
} else {
current_derive.push_str(token.text().trim());
}
} }
if !current_derive.is_empty() { if !input.is_empty() {
input_derives.insert(current_derive); input_derives.insert(input.trim().to_owned());
} }
input.clear();
}
Some(input_derives) Some(input_derives)
} }

View file

@ -45,6 +45,7 @@ pub(super) fn complete_derive(
} }
} }
} }
fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> { fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> {
let mut result = FxHashSet::default(); let mut result = FxHashSet::default();
ctx.scope.process_all_names(&mut |name, scope_def| { ctx.scope.process_all_names(&mut |name, scope_def| {
@ -89,12 +90,14 @@ mod tests {
} }
#[test] #[test]
fn empty_derive_completion() { fn no_completion_for_incorrect_derive() {
check(r#"#[derive{$0)] struct Test;"#, expect![[]])
}
#[test]
fn empty_derive() {
check( check(
r#" r#"#[derive($0)] struct Test;"#,
#[derive($0)]
struct Test {}
"#,
expect![[r#" expect![[r#"
at Clone at Clone
at Clone, Copy at Clone, Copy
@ -110,23 +113,26 @@ struct Test {}
} }
#[test] #[test]
fn no_completion_for_incorrect_derive() { fn derive_with_input() {
check( check(
r#" r#"#[derive(serde::Serialize, PartialEq, $0)] struct Test;"#,
#[derive{$0)] expect![[r#"
struct Test {} at Clone
"#, at Clone, Copy
expect![[r#""#]], at Debug
at Default
at Hash
at Eq
at PartialOrd
at Eq, PartialOrd, Ord
"#]],
) )
} }
#[test] #[test]
fn derive_with_input_completion() { fn derive_with_input2() {
check( check(
r#" r#"#[derive($0 serde::Serialize, PartialEq)] struct Test;"#,
#[derive(serde::Serialize, PartialEq, $0)]
struct Test {}
"#,
expect![[r#" expect![[r#"
at Clone at Clone
at Clone, Copy at Clone, Copy

View file

@ -152,3 +152,36 @@ pub(super) const DEFAULT_LINT_COMPLETIONS: &[LintCompletion] = &[
LintCompletion { label: "unconditional_panic", description: r#"operation will cause a panic at runtime"# }, 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"# }, 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;"#,
)
}
}