aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r--crates/ide_completion/src/context.rs63
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
18use crate::{ 18use 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)]
35pub(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)]
46pub(crate) enum PrevSibling { 33pub(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
130impl<'a> CompletionContext<'a> { 118impl<'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) {