Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal: Add some lint completion tests #9048

Merged
merged 1 commit into from
May 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions crates/ide_completion/src/completions/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -272,27 +270,27 @@ const ATTRIBUTES: &[AttrCompletion] = &[
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 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 !current_derive.is_empty() {
input_derives.insert(current_derive);
if !input.is_empty() {
input_derives.insert(input.trim().to_owned());
}

input.clear();
}

Some(input_derives)
}

Expand Down
38 changes: 22 additions & 16 deletions crates/ide_completion/src/completions/attribute/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub(super) fn complete_derive(
}
}
}

fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> {
let mut result = FxHashSet::default();
ctx.scope.process_all_names(&mut |name, scope_def| {
Expand Down Expand Up @@ -89,12 +90,14 @@ mod tests {
}

#[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
Expand All @@ -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
Expand Down
33 changes: 33 additions & 0 deletions crates/ide_completion/src/completions/attribute/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: "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;"#,
)
}
}