aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/patterns.rs')
-rw-r--r--crates/ide_completion/src/patterns.rs28
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)]
14use crate::test_utils::{check_pattern_is_applicable, check_pattern_is_not_applicable}; 14use 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> {
310mod tests { 324mod 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}