diff options
Diffstat (limited to 'crates/ide_completion')
-rw-r--r-- | crates/ide_completion/src/completions/fn_param.rs | 2 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/trait_impl.rs | 7 | ||||
-rw-r--r-- | crates/ide_completion/src/context.rs | 15 | ||||
-rw-r--r-- | crates/ide_completion/src/patterns.rs | 16 |
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 | ||
83 | fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { | 83 | fn 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 | ||
186 | pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { | 186 | pub(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 | })?; |