aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-16 13:14:48 +0000
committerGitHub <[email protected]>2021-03-16 13:14:48 +0000
commitc49b5b7468a9954af86fd1724276261f396aba5d (patch)
treef9b9126cd0cc9a2829de3cdb20f681b354fbe67b /crates/ide_completion
parent1a82af3527e476d52410ff4dfd2fb4c57466abcb (diff)
parentf5a81ec4683613bd62624811733345d627f2127b (diff)
Merge #7498
7498: Clone for update r=matklad a=matklad rowan counterpart https://github.com/rust-analyzer/rowan/pull/93 #6857 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ide_completion')
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs2
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs7
-rw-r--r--crates/ide_completion/src/context.rs15
-rw-r--r--crates/ide_completion/src/patterns.rs16
4 files changed, 18 insertions, 22 deletions
diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs
index 0243dce56..0ea558489 100644
--- a/crates/ide_completion/src/completions/fn_param.rs
+++ b/crates/ide_completion/src/completions/fn_param.rs
@@ -33,7 +33,7 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
33 }); 33 });
34 }; 34 };
35 35
36 for node in ctx.token.parent().ancestors() { 36 for node in ctx.token.ancestors() {
37 match_ast! { 37 match_ast! {
38 match node { 38 match node {
39 ast::SourceFile(it) => it.items().filter_map(|item| match item { 39 ast::SourceFile(it) => it.items().filter_map(|item| match item {
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs
index 5a7361f8e..a26fe7c6c 100644
--- a/crates/ide_completion/src/completions/trait_impl.rs
+++ b/crates/ide_completion/src/completions/trait_impl.rs
@@ -82,13 +82,14 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
82 82
83fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { 83fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> {
84 let mut token = ctx.token.clone(); 84 let mut token = ctx.token.clone();
85 // For keywork without name like `impl .. { fn $0 }`, the current position is inside 85 // For keyword without name like `impl .. { fn $0 }`, the current position is inside
86 // the whitespace token, which is outside `FN` syntax node. 86 // the whitespace token, which is outside `FN` syntax node.
87 // We need to follow the previous token in this case. 87 // We need to follow the previous token in this case.
88 if token.kind() == SyntaxKind::WHITESPACE { 88 if token.kind() == SyntaxKind::WHITESPACE {
89 token = token.prev_token()?; 89 token = token.prev_token()?;
90 } 90 }
91 91
92 let parent_kind = token.parent().map_or(SyntaxKind::EOF, |it| it.kind());
92 let impl_item_offset = match token.kind() { 93 let impl_item_offset = match token.kind() {
93 // `impl .. { const $0 }` 94 // `impl .. { const $0 }`
94 // ERROR 0 95 // ERROR 0
@@ -102,14 +103,14 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt
102 // FN/TYPE_ALIAS/CONST 1 103 // FN/TYPE_ALIAS/CONST 1
103 // NAME 0 104 // NAME 0
104 // IDENT <- * 105 // IDENT <- *
105 SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1, 106 SyntaxKind::IDENT if parent_kind == SyntaxKind::NAME => 1,
106 // `impl .. { foo$0 }` 107 // `impl .. { foo$0 }`
107 // MACRO_CALL 3 108 // MACRO_CALL 3
108 // PATH 2 109 // PATH 2
109 // PATH_SEGMENT 1 110 // PATH_SEGMENT 1
110 // NAME_REF 0 111 // NAME_REF 0
111 // IDENT <- * 112 // IDENT <- *
112 SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME_REF => 3, 113 SyntaxKind::IDENT if parent_kind == SyntaxKind::NAME_REF => 3,
113 _ => return None, 114 _ => return None,
114 }; 115 };
115 116
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index e6cc6329c..8cbbdb477 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -120,7 +120,7 @@ impl<'a> CompletionContext<'a> {
120 let original_token = 120 let original_token =
121 original_file.syntax().token_at_offset(position.offset).left_biased()?; 121 original_file.syntax().token_at_offset(position.offset).left_biased()?;
122 let token = sema.descend_into_macros(original_token.clone()); 122 let token = sema.descend_into_macros(original_token.clone());
123 let scope = sema.scope_at_offset(&token.parent(), position.offset); 123 let scope = sema.scope_at_offset(&token, position.offset);
124 let mut locals = vec![]; 124 let mut locals = vec![];
125 scope.process_all_names(&mut |name, scope| { 125 scope.process_all_names(&mut |name, scope| {
126 if let ScopeDef::Local(local) = scope { 126 if let ScopeDef::Local(local) = scope {
@@ -281,7 +281,7 @@ impl<'a> CompletionContext<'a> {
281 fn fill_impl_def(&mut self) { 281 fn fill_impl_def(&mut self) {
282 self.impl_def = self 282 self.impl_def = self
283 .sema 283 .sema
284 .ancestors_with_macros(self.token.parent()) 284 .token_ancestors_with_macros(self.token.clone())
285 .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) 285 .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
286 .find_map(ast::Impl::cast); 286 .find_map(ast::Impl::cast);
287 } 287 }
@@ -293,7 +293,10 @@ impl<'a> CompletionContext<'a> {
293 offset: TextSize, 293 offset: TextSize,
294 ) { 294 ) {
295 let expected = { 295 let expected = {
296 let mut node = self.token.parent(); 296 let mut node = match self.token.parent() {
297 Some(it) => it,
298 None => return,
299 };
297 loop { 300 loop {
298 let ret = match_ast! { 301 let ret = match_ast! {
299 match node { 302 match node {
@@ -474,17 +477,17 @@ impl<'a> CompletionContext<'a> {
474 } 477 }
475 478
476 self.use_item_syntax = 479 self.use_item_syntax =
477 self.sema.ancestors_with_macros(self.token.parent()).find_map(ast::Use::cast); 480 self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast);
478 481
479 self.function_syntax = self 482 self.function_syntax = self
480 .sema 483 .sema
481 .ancestors_with_macros(self.token.parent()) 484 .token_ancestors_with_macros(self.token.clone())
482 .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE) 485 .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
483 .find_map(ast::Fn::cast); 486 .find_map(ast::Fn::cast);
484 487
485 self.record_field_syntax = self 488 self.record_field_syntax = self
486 .sema 489 .sema
487 .ancestors_with_macros(self.token.parent()) 490 .token_ancestors_with_macros(self.token.clone())
488 .take_while(|it| { 491 .take_while(|it| {
489 it.kind() != SOURCE_FILE && it.kind() != MODULE && it.kind() != CALL_EXPR 492 it.kind() != SOURCE_FILE && it.kind() != MODULE && it.kind() != CALL_EXPR
490 }) 493 })
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs
index f3ce91dd1..cf5ef07b7 100644
--- a/crates/ide_completion/src/patterns.rs
+++ b/crates/ide_completion/src/patterns.rs
@@ -184,11 +184,7 @@ fn test_has_impl_as_prev_sibling() {
184} 184}
185 185
186pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { 186pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
187 let leaf = match element { 187 for node in element.ancestors() {
188 NodeOrToken::Node(node) => node,
189 NodeOrToken::Token(token) => token.parent(),
190 };
191 for node in leaf.ancestors() {
192 if node.kind() == FN || node.kind() == CLOSURE_EXPR { 188 if node.kind() == FN || node.kind() == CLOSURE_EXPR {
193 break; 189 break;
194 } 190 }
@@ -201,7 +197,7 @@ pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
201 } 197 }
202 }; 198 };
203 if let Some(body) = loop_body { 199 if let Some(body) = loop_body {
204 if body.syntax().text_range().contains_range(leaf.text_range()) { 200 if body.syntax().text_range().contains_range(element.text_range()) {
205 return true; 201 return true;
206 } 202 }
207 } 203 }
@@ -235,12 +231,8 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax
235 Some(sibling) 231 Some(sibling)
236 } else { 232 } else {
237 // if not trying to find first ancestor which has such a sibling 233 // if not trying to find first ancestor which has such a sibling
238 let node = match element { 234 let range = element.text_range();
239 NodeOrToken::Node(node) => node, 235 let top_node = element.ancestors().take_while(|it| it.text_range() == range).last()?;
240 NodeOrToken::Token(token) => token.parent(),
241 };
242 let range = node.text_range();
243 let top_node = node.ancestors().take_while(|it| it.text_range() == range).last()?;
244 let prev_sibling_node = top_node.ancestors().find(|it| { 236 let prev_sibling_node = top_node.ancestors().find(|it| {
245 non_trivia_sibling(NodeOrToken::Node(it.to_owned()), Direction::Prev).is_some() 237 non_trivia_sibling(NodeOrToken::Node(it.to_owned()), Direction::Prev).is_some()
246 })?; 238 })?;