diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-27 17:34:46 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-27 17:34:46 +0100 |
commit | a2940c42c0ab30e80e1a63494ca17fb2d81bdd1f (patch) | |
tree | 7d755c4edd86c0b031452eb45536eb42d802f65c /crates/ide_completion/src/context.rs | |
parent | cc5d8069219a0a52f9c98b6766d2421eaf4664d8 (diff) | |
parent | 3a16950fd919f46fd879c36423810a40105b2c10 (diff) |
Merge #9020
9020: fix: Don't complete non-macro item paths in impls and modules r=Veykril a=Veykril
Part of #8518
bors r+
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r-- | crates/ide_completion/src/context.rs | 63 |
1 files changed, 18 insertions, 45 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 66577df94..fbef54408 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -17,9 +17,8 @@ use text_edit::Indel; | |||
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | patterns::{ | 19 | patterns::{ |
20 | for_is_prev2, has_bind_pat_parent, has_block_expr_parent, has_field_list_parent, | 20 | determine_location, for_is_prev2, has_prev_sibling, inside_impl_trait_block, |
21 | has_impl_parent, has_item_list_or_source_file_parent, has_prev_sibling, has_ref_parent, | 21 | is_in_loop_body, is_match_arm, previous_token, ImmediateLocation, |
22 | has_trait_parent, inside_impl_trait_block, is_in_loop_body, is_match_arm, previous_token, | ||
23 | }, | 22 | }, |
24 | CompletionConfig, | 23 | CompletionConfig, |
25 | }; | 24 | }; |
@@ -30,18 +29,6 @@ pub(crate) enum PatternRefutability { | |||
30 | Irrefutable, | 29 | Irrefutable, |
31 | } | 30 | } |
32 | 31 | ||
33 | /// Direct parent container of the cursor position | ||
34 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
35 | pub(crate) enum ImmediateLocation { | ||
36 | Impl, | ||
37 | Trait, | ||
38 | RecordFieldList, | ||
39 | RefPatOrExpr, | ||
40 | IdentPat, | ||
41 | BlockExpr, | ||
42 | ItemList, | ||
43 | } | ||
44 | |||
45 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | 32 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
46 | pub(crate) enum PrevSibling { | 33 | pub(crate) enum PrevSibling { |
47 | Trait, | 34 | Trait, |
@@ -127,6 +114,7 @@ pub(crate) struct CompletionContext<'a> { | |||
127 | 114 | ||
128 | no_completion_required: bool, | 115 | no_completion_required: bool, |
129 | } | 116 | } |
117 | |||
130 | impl<'a> CompletionContext<'a> { | 118 | impl<'a> CompletionContext<'a> { |
131 | pub(super) fn new( | 119 | pub(super) fn new( |
132 | db: &'a RootDatabase, | 120 | db: &'a RootDatabase, |
@@ -281,34 +269,34 @@ impl<'a> CompletionContext<'a> { | |||
281 | self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind) | 269 | self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind) |
282 | } | 270 | } |
283 | 271 | ||
284 | pub(crate) fn has_impl_or_trait_parent(&self) -> bool { | 272 | pub(crate) fn expects_assoc_item(&self) -> bool { |
285 | matches!( | 273 | matches!( |
286 | self.completion_location, | 274 | self.completion_location, |
287 | Some(ImmediateLocation::Trait) | Some(ImmediateLocation::Impl) | 275 | Some(ImmediateLocation::Trait) | Some(ImmediateLocation::Impl) |
288 | ) | 276 | ) |
289 | } | 277 | } |
290 | 278 | ||
291 | pub(crate) fn has_block_expr_parent(&self) -> bool { | 279 | pub(crate) fn expects_non_trait_assoc_item(&self) -> bool { |
292 | matches!(self.completion_location, Some(ImmediateLocation::BlockExpr)) | 280 | matches!(self.completion_location, Some(ImmediateLocation::Impl)) |
293 | } | 281 | } |
294 | 282 | ||
295 | pub(crate) fn has_item_list_parent(&self) -> bool { | 283 | pub(crate) fn expects_item(&self) -> bool { |
296 | matches!(self.completion_location, Some(ImmediateLocation::ItemList)) | 284 | matches!(self.completion_location, Some(ImmediateLocation::ItemList)) |
297 | } | 285 | } |
298 | 286 | ||
299 | pub(crate) fn has_ident_or_ref_pat_parent(&self) -> bool { | 287 | pub(crate) fn has_block_expr_parent(&self) -> bool { |
288 | matches!(self.completion_location, Some(ImmediateLocation::BlockExpr)) | ||
289 | } | ||
290 | |||
291 | pub(crate) fn expects_ident_pat_or_ref_expr(&self) -> bool { | ||
300 | matches!( | 292 | matches!( |
301 | self.completion_location, | 293 | self.completion_location, |
302 | Some(ImmediateLocation::IdentPat) | Some(ImmediateLocation::RefPatOrExpr) | 294 | Some(ImmediateLocation::IdentPat) | Some(ImmediateLocation::RefExpr) |
303 | ) | 295 | ) |
304 | } | 296 | } |
305 | 297 | ||
306 | pub(crate) fn has_impl_parent(&self) -> bool { | 298 | pub(crate) fn expect_record_field(&self) -> bool { |
307 | matches!(self.completion_location, Some(ImmediateLocation::Impl)) | 299 | matches!(self.completion_location, Some(ImmediateLocation::RecordField)) |
308 | } | ||
309 | |||
310 | pub(crate) fn has_field_list_parent(&self) -> bool { | ||
311 | matches!(self.completion_location, Some(ImmediateLocation::RecordFieldList)) | ||
312 | } | 300 | } |
313 | 301 | ||
314 | pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { | 302 | pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { |
@@ -320,12 +308,11 @@ impl<'a> CompletionContext<'a> { | |||
320 | || self.record_pat_syntax.is_some() | 308 | || self.record_pat_syntax.is_some() |
321 | || self.attribute_under_caret.is_some() | 309 | || self.attribute_under_caret.is_some() |
322 | || self.mod_declaration_under_caret.is_some() | 310 | || self.mod_declaration_under_caret.is_some() |
323 | || self.has_impl_or_trait_parent() | ||
324 | } | 311 | } |
325 | 312 | ||
326 | fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { | 313 | fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { |
327 | let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); | 314 | let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); |
328 | let syntax_element = NodeOrToken::Token(fake_ident_token); | 315 | let syntax_element = NodeOrToken::Token(fake_ident_token.clone()); |
329 | self.previous_token = previous_token(syntax_element.clone()); | 316 | self.previous_token = previous_token(syntax_element.clone()); |
330 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); | 317 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); |
331 | self.is_match_arm = is_match_arm(syntax_element.clone()); | 318 | self.is_match_arm = is_match_arm(syntax_element.clone()); |
@@ -335,22 +322,6 @@ impl<'a> CompletionContext<'a> { | |||
335 | self.prev_sibling = Some(PrevSibling::Trait) | 322 | self.prev_sibling = Some(PrevSibling::Trait) |
336 | } | 323 | } |
337 | 324 | ||
338 | if has_block_expr_parent(syntax_element.clone()) { | ||
339 | self.completion_location = Some(ImmediateLocation::BlockExpr); | ||
340 | } else if has_bind_pat_parent(syntax_element.clone()) { | ||
341 | self.completion_location = Some(ImmediateLocation::IdentPat); | ||
342 | } else if has_ref_parent(syntax_element.clone()) { | ||
343 | self.completion_location = Some(ImmediateLocation::RefPatOrExpr); | ||
344 | } else if has_impl_parent(syntax_element.clone()) { | ||
345 | self.completion_location = Some(ImmediateLocation::Impl); | ||
346 | } else if has_field_list_parent(syntax_element.clone()) { | ||
347 | self.completion_location = Some(ImmediateLocation::RecordFieldList); | ||
348 | } else if has_trait_parent(syntax_element.clone()) { | ||
349 | self.completion_location = Some(ImmediateLocation::Trait); | ||
350 | } else if has_item_list_or_source_file_parent(syntax_element.clone()) { | ||
351 | self.completion_location = Some(ImmediateLocation::ItemList); | ||
352 | } | ||
353 | |||
354 | self.mod_declaration_under_caret = | 325 | self.mod_declaration_under_caret = |
355 | find_node_at_offset::<ast::Module>(&file_with_fake_ident, offset) | 326 | find_node_at_offset::<ast::Module>(&file_with_fake_ident, offset) |
356 | .filter(|module| module.item_list().is_none()); | 327 | .filter(|module| module.item_list().is_none()); |
@@ -363,6 +334,8 @@ impl<'a> CompletionContext<'a> { | |||
363 | let fn_is_prev = self.previous_token_is(T![fn]); | 334 | let fn_is_prev = self.previous_token_is(T![fn]); |
364 | let for_is_prev2 = for_is_prev2(syntax_element.clone()); | 335 | let for_is_prev2 = for_is_prev2(syntax_element.clone()); |
365 | self.no_completion_required = (fn_is_prev && !inside_impl_trait_block) || for_is_prev2; | 336 | self.no_completion_required = (fn_is_prev && !inside_impl_trait_block) || for_is_prev2; |
337 | |||
338 | self.completion_location = determine_location(fake_ident_token); | ||
366 | } | 339 | } |
367 | 340 | ||
368 | fn fill_impl_def(&mut self) { | 341 | fn fill_impl_def(&mut self) { |