diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-06-16 20:53:43 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-06-16 20:53:43 +0100 |
commit | d6b8af44829521a9f925c4d87599efa3fef38edc (patch) | |
tree | 47119538effd381ecd8e15d422103512f2b47406 /crates/ide_completion/src/patterns.rs | |
parent | f38770cd2606148bfe764351849ea7ebea45132c (diff) | |
parent | aa644b55859c6b5c6695a5d4fb35d1b6efbbebcc (diff) |
Merge #9301
9301: internal: Start refactoring ide_completion tests r=Veykril a=Veykril
Our current completion test infra resovles around usually just checking a specific `CompletionKind` which is suboptimal. We only see what we want to see in tests with this causing us to miss a lot of incorrect completions we are doing. Instead we should test for different cursor locations for all kinds(sans the magic kind maybe? not sure yet). This way we will also see potential duplicate completions that merely different in their kind.
Also since most completion submodules complete things in tests of other modules due to the tests overlapping it makes more sense to group these tests differently which implies moving them to a new module. Exceptions for this might be stuff like attribute completion as these cannot currently interfere.
I only wrote a few tests to check for completions in `ItemList` position so far and I already found a few incorrect/irrelevant completions as these haven't been tested properly due to them being hidden by the `CompletionKind` filtering.
I think `CompletionKind` doesn't really seem to be beneficial to me as to I can't think of a occasion where we would want to only check a specific completion kind.
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/ide_completion/src/patterns.rs')
-rw-r--r-- | crates/ide_completion/src/patterns.rs | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs index 72e67e3c4..62e4334de 100644 --- a/crates/ide_completion/src/patterns.rs +++ b/crates/ide_completion/src/patterns.rs | |||
@@ -11,7 +11,7 @@ use syntax::{ | |||
11 | }; | 11 | }; |
12 | 12 | ||
13 | #[cfg(test)] | 13 | #[cfg(test)] |
14 | use crate::test_utils::{check_pattern_is_applicable, check_pattern_is_not_applicable}; | 14 | use crate::tests::{check_pattern_is_applicable, check_pattern_is_not_applicable}; |
15 | 15 | ||
16 | /// Immediate previous node to what we are completing. | 16 | /// Immediate previous node to what we are completing. |
17 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | 17 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
@@ -19,6 +19,8 @@ pub(crate) enum ImmediatePrevSibling { | |||
19 | IfExpr, | 19 | IfExpr, |
20 | TraitDefName, | 20 | TraitDefName, |
21 | ImplDefType, | 21 | ImplDefType, |
22 | Visibility, | ||
23 | Attribute, | ||
22 | } | 24 | } |
23 | 25 | ||
24 | /// Direct parent "thing" of what we are currently completing. | 26 | /// Direct parent "thing" of what we are currently completing. |
@@ -79,6 +81,17 @@ pub(crate) fn determine_prev_sibling(name_like: &ast::NameLike) -> Option<Immedi | |||
79 | _ => node, | 81 | _ => node, |
80 | }; | 82 | }; |
81 | let prev_sibling = non_trivia_sibling(node.into(), Direction::Prev)?.into_node()?; | 83 | let prev_sibling = non_trivia_sibling(node.into(), Direction::Prev)?.into_node()?; |
84 | if prev_sibling.kind() == ERROR { | ||
85 | let prev_sibling = prev_sibling.first_child()?; | ||
86 | let res = match_ast! { | ||
87 | match prev_sibling { | ||
88 | // vis followed by random ident will always error the parser | ||
89 | ast::Visibility(_it) => ImmediatePrevSibling::Visibility, | ||
90 | _ => return None, | ||
91 | } | ||
92 | }; | ||
93 | return Some(res); | ||
94 | } | ||
82 | let res = match_ast! { | 95 | let res = match_ast! { |
83 | match prev_sibling { | 96 | match prev_sibling { |
84 | ast::ExprStmt(it) => { | 97 | ast::ExprStmt(it) => { |
@@ -101,6 +114,7 @@ pub(crate) fn determine_prev_sibling(name_like: &ast::NameLike) -> Option<Immedi | |||
101 | } else { | 114 | } else { |
102 | return None | 115 | return None |
103 | }, | 116 | }, |
117 | ast::Attr(_it) => ImmediatePrevSibling::Attribute, | ||
104 | _ => return None, | 118 | _ => return None, |
105 | } | 119 | } |
106 | }; | 120 | }; |
@@ -310,7 +324,7 @@ fn previous_non_trivia_token(token: SyntaxToken) -> Option<SyntaxToken> { | |||
310 | mod tests { | 324 | mod tests { |
311 | use syntax::algo::find_node_at_offset; | 325 | use syntax::algo::find_node_at_offset; |
312 | 326 | ||
313 | use crate::test_utils::position; | 327 | use crate::tests::position; |
314 | 328 | ||
315 | use super::*; | 329 | use super::*; |
316 | 330 | ||
@@ -421,4 +435,14 @@ mod tests { | |||
421 | check_prev_sibling(r"fn foo() { if true {} w$0", ImmediatePrevSibling::IfExpr); | 435 | check_prev_sibling(r"fn foo() { if true {} w$0", ImmediatePrevSibling::IfExpr); |
422 | check_prev_sibling(r"fn foo() { if true {}; w$0", None); | 436 | check_prev_sibling(r"fn foo() { if true {}; w$0", None); |
423 | } | 437 | } |
438 | |||
439 | #[test] | ||
440 | fn test_vis_prev_sibling() { | ||
441 | check_prev_sibling(r"pub w$0", ImmediatePrevSibling::Visibility); | ||
442 | } | ||
443 | |||
444 | #[test] | ||
445 | fn test_attr_prev_sibling() { | ||
446 | check_prev_sibling(r"#[attr] w$0", ImmediatePrevSibling::Attribute); | ||
447 | } | ||
424 | } | 448 | } |