aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-05-26 20:09:27 +0100
committerLukas Wirth <[email protected]>2021-05-26 20:09:27 +0100
commit26e784a575c760087bdb321932e823ad27046024 (patch)
treed63bfa5a27928f55828c7c38b669e2105bb9baf9 /crates/ide_completion/src/context.rs
parentbb1c7fc0cfe24a8477d943faa932992b9cd48957 (diff)
simplify
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r--crates/ide_completion/src/context.rs63
1 files changed, 34 insertions, 29 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 2f3fb1710..85c7edabb 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -1,25 +1,26 @@
1//! See `CompletionContext` structure. 1//! See `CompletionContext` structure.
2 2
3use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type}; 3use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
4use ide_db::base_db::{FilePosition, SourceDatabase}; 4use ide_db::{
5use ide_db::{call_info::ActiveParameter, RootDatabase}; 5 base_db::{FilePosition, SourceDatabase},
6 call_info::ActiveParameter,
7 RootDatabase,
8};
6use syntax::{ 9use syntax::{
7 algo::find_node_at_offset, 10 algo::find_node_at_offset,
8 ast::{self, NameOrNameRef, NameOwner}, 11 ast::{self, NameOrNameRef, NameOwner},
9 match_ast, AstNode, NodeOrToken, 12 match_ast, AstNode, NodeOrToken,
10 SyntaxKind::*, 13 SyntaxKind::{self, *},
11 SyntaxNode, SyntaxToken, TextRange, TextSize, 14 SyntaxNode, SyntaxToken, TextRange, TextSize, T,
12}; 15};
13
14use text_edit::Indel; 16use text_edit::Indel;
15 17
16use crate::{ 18use crate::{
17 patterns::{ 19 patterns::{
18 fn_is_prev, for_is_prev2, has_bind_pat_parent, has_block_expr_parent, 20 for_is_prev2, has_bind_pat_parent, has_block_expr_parent, has_field_list_parent,
19 has_field_list_parent, has_impl_as_prev_sibling, has_impl_parent, 21 has_impl_as_prev_sibling, has_impl_parent, has_item_list_or_source_file_parent,
20 has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling, 22 has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, inside_impl_trait_block,
21 has_trait_parent, if_is_prev, inside_impl_trait_block, is_in_loop_body, is_match_arm, 23 is_in_loop_body, is_match_arm, previous_token,
22 unsafe_is_prev,
23 }, 24 },
24 CompletionConfig, 25 CompletionConfig,
25}; 26};
@@ -81,25 +82,26 @@ pub(crate) struct CompletionContext<'a> {
81 pub(super) is_path_type: bool, 82 pub(super) is_path_type: bool,
82 pub(super) has_type_args: bool, 83 pub(super) has_type_args: bool,
83 pub(super) attribute_under_caret: Option<ast::Attr>, 84 pub(super) attribute_under_caret: Option<ast::Attr>,
85 pub(super) locals: Vec<(String, Local)>,
86
84 pub(super) mod_declaration_under_caret: Option<ast::Module>, 87 pub(super) mod_declaration_under_caret: Option<ast::Module>,
85 pub(super) unsafe_is_prev: bool, 88 pub(super) has_trait_parent: bool,
86 pub(super) if_is_prev: bool, 89 pub(super) has_impl_parent: bool,
90
91 // keyword patterns
92 pub(super) previous_token: Option<SyntaxToken>,
87 pub(super) block_expr_parent: bool, 93 pub(super) block_expr_parent: bool,
88 pub(super) bind_pat_parent: bool, 94 pub(super) bind_pat_parent: bool,
89 pub(super) ref_pat_parent: bool, 95 pub(super) ref_pat_parent: bool,
90 pub(super) in_loop_body: bool, 96 pub(super) in_loop_body: bool,
91 pub(super) has_trait_parent: bool,
92 pub(super) has_impl_parent: bool,
93 pub(super) inside_impl_trait_block: bool,
94 pub(super) has_field_list_parent: bool, 97 pub(super) has_field_list_parent: bool,
95 pub(super) trait_as_prev_sibling: bool, 98 pub(super) trait_as_prev_sibling: bool,
96 pub(super) impl_as_prev_sibling: bool, 99 pub(super) impl_as_prev_sibling: bool,
97 pub(super) is_match_arm: bool, 100 pub(super) is_match_arm: bool,
98 pub(super) has_item_list_or_source_file_parent: bool, 101 pub(super) has_item_list_or_source_file_parent: bool,
99 pub(super) for_is_prev2: bool,
100 pub(super) fn_is_prev: bool,
101 pub(super) incomplete_let: bool, 102 pub(super) incomplete_let: bool,
102 pub(super) locals: Vec<(String, Local)>, 103
104 no_completion_required: bool,
103} 105}
104 106
105impl<'a> CompletionContext<'a> { 107impl<'a> CompletionContext<'a> {
@@ -175,22 +177,19 @@ impl<'a> CompletionContext<'a> {
175 has_type_args: false, 177 has_type_args: false,
176 attribute_under_caret: None, 178 attribute_under_caret: None,
177 mod_declaration_under_caret: None, 179 mod_declaration_under_caret: None,
178 unsafe_is_prev: false, 180 previous_token: None,
179 if_is_prev: false,
180 block_expr_parent: false, 181 block_expr_parent: false,
181 bind_pat_parent: false, 182 bind_pat_parent: false,
182 ref_pat_parent: false, 183 ref_pat_parent: false,
183 in_loop_body: false, 184 in_loop_body: false,
184 has_trait_parent: false, 185 has_trait_parent: false,
185 has_impl_parent: false, 186 has_impl_parent: false,
186 inside_impl_trait_block: false,
187 has_field_list_parent: false, 187 has_field_list_parent: false,
188 trait_as_prev_sibling: false, 188 trait_as_prev_sibling: false,
189 impl_as_prev_sibling: false, 189 impl_as_prev_sibling: false,
190 is_match_arm: false, 190 is_match_arm: false,
191 has_item_list_or_source_file_parent: false, 191 has_item_list_or_source_file_parent: false,
192 for_is_prev2: false, 192 no_completion_required: false,
193 fn_is_prev: false,
194 incomplete_let: false, 193 incomplete_let: false,
195 locals, 194 locals,
196 }; 195 };
@@ -245,7 +244,7 @@ impl<'a> CompletionContext<'a> {
245 /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names. 244 /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names.
246 /// - `for _ i$0` -- obviously, it'll be "in" keyword. 245 /// - `for _ i$0` -- obviously, it'll be "in" keyword.
247 pub(crate) fn no_completion_required(&self) -> bool { 246 pub(crate) fn no_completion_required(&self) -> bool {
248 (self.fn_is_prev && !self.inside_impl_trait_block) || self.for_is_prev2 247 self.no_completion_required
249 } 248 }
250 249
251 /// The range of the identifier that is being completed. 250 /// The range of the identifier that is being completed.
@@ -264,33 +263,39 @@ impl<'a> CompletionContext<'a> {
264 } 263 }
265 } 264 }
266 265
266 pub(crate) fn previous_token_is(&self, kind: SyntaxKind) -> bool {
267 self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
268 }
269
267 fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { 270 fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) {
268 let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); 271 let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
269 let syntax_element = NodeOrToken::Token(fake_ident_token); 272 let syntax_element = NodeOrToken::Token(fake_ident_token);
273 self.previous_token = previous_token(syntax_element.clone());
270 self.block_expr_parent = has_block_expr_parent(syntax_element.clone()); 274 self.block_expr_parent = has_block_expr_parent(syntax_element.clone());
271 self.unsafe_is_prev = unsafe_is_prev(syntax_element.clone());
272 self.if_is_prev = if_is_prev(syntax_element.clone());
273 self.bind_pat_parent = has_bind_pat_parent(syntax_element.clone()); 275 self.bind_pat_parent = has_bind_pat_parent(syntax_element.clone());
274 self.ref_pat_parent = has_ref_parent(syntax_element.clone()); 276 self.ref_pat_parent = has_ref_parent(syntax_element.clone());
275 self.in_loop_body = is_in_loop_body(syntax_element.clone()); 277 self.in_loop_body = is_in_loop_body(syntax_element.clone());
276 self.has_trait_parent = has_trait_parent(syntax_element.clone()); 278 self.has_trait_parent = has_trait_parent(syntax_element.clone());
277 self.has_impl_parent = has_impl_parent(syntax_element.clone()); 279 self.has_impl_parent = has_impl_parent(syntax_element.clone());
278 self.inside_impl_trait_block = inside_impl_trait_block(syntax_element.clone());
279 self.has_field_list_parent = has_field_list_parent(syntax_element.clone()); 280 self.has_field_list_parent = has_field_list_parent(syntax_element.clone());
280 self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); 281 self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone());
281 self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); 282 self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone());
282 self.is_match_arm = is_match_arm(syntax_element.clone()); 283 self.is_match_arm = is_match_arm(syntax_element.clone());
284
283 self.has_item_list_or_source_file_parent = 285 self.has_item_list_or_source_file_parent =
284 has_item_list_or_source_file_parent(syntax_element.clone()); 286 has_item_list_or_source_file_parent(syntax_element.clone());
285 self.mod_declaration_under_caret = 287 self.mod_declaration_under_caret =
286 find_node_at_offset::<ast::Module>(&file_with_fake_ident, offset) 288 find_node_at_offset::<ast::Module>(&file_with_fake_ident, offset)
287 .filter(|module| module.item_list().is_none()); 289 .filter(|module| module.item_list().is_none());
288 self.for_is_prev2 = for_is_prev2(syntax_element.clone());
289 self.fn_is_prev = fn_is_prev(syntax_element.clone());
290 self.incomplete_let = 290 self.incomplete_let =
291 syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| { 291 syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
292 it.syntax().text_range().end() == syntax_element.text_range().end() 292 it.syntax().text_range().end() == syntax_element.text_range().end()
293 }); 293 });
294
295 let inside_impl_trait_block = inside_impl_trait_block(syntax_element.clone());
296 let fn_is_prev = self.previous_token_is(T![fn]);
297 let for_is_prev2 = for_is_prev2(syntax_element.clone());
298 self.no_completion_required = (fn_is_prev && !inside_impl_trait_block) || for_is_prev2;
294 } 299 }
295 300
296 fn fill_impl_def(&mut self) { 301 fn fill_impl_def(&mut self) {