diff options
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r-- | crates/ide_completion/src/completions.rs | 1 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/keyword.rs | 20 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/macro_in_item_position.rs | 48 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/qualified_path.rs | 11 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/snippet.rs | 14 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/trait_impl.rs | 18 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/unqualified_path.rs | 22 | ||||
-rw-r--r-- | crates/ide_completion/src/context.rs | 44 | ||||
-rw-r--r-- | crates/ide_completion/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ide_completion/src/patterns.rs | 7 |
10 files changed, 63 insertions, 123 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs index ffdcdc930..7a4d71e91 100644 --- a/crates/ide_completion/src/completions.rs +++ b/crates/ide_completion/src/completions.rs | |||
@@ -6,7 +6,6 @@ pub(crate) mod flyimport; | |||
6 | pub(crate) mod fn_param; | 6 | pub(crate) mod fn_param; |
7 | pub(crate) mod keyword; | 7 | pub(crate) mod keyword; |
8 | pub(crate) mod lifetime; | 8 | pub(crate) mod lifetime; |
9 | pub(crate) mod macro_in_item_position; | ||
10 | pub(crate) mod mod_; | 9 | pub(crate) mod mod_; |
11 | pub(crate) mod pattern; | 10 | pub(crate) mod pattern; |
12 | pub(crate) mod postfix; | 11 | pub(crate) mod postfix; |
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index 0ca97a0e4..ba13d3707 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs | |||
@@ -5,8 +5,8 @@ use std::iter; | |||
5 | use syntax::{SyntaxKind, T}; | 5 | use syntax::{SyntaxKind, T}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, | 8 | context::PathCompletionContext, patterns::ImmediateLocation, CompletionContext, CompletionItem, |
9 | CompletionKind, Completions, | 9 | CompletionItemKind, CompletionKind, Completions, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { | 12 | pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { |
@@ -128,8 +128,15 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
128 | add_keyword("mut", "mut "); | 128 | add_keyword("mut", "mut "); |
129 | } | 129 | } |
130 | 130 | ||
131 | if ctx.in_loop_body { | 131 | let (can_be_stmt, in_loop_body) = match ctx.path_context { |
132 | if ctx.can_be_stmt() { | 132 | Some(PathCompletionContext { |
133 | is_trivial_path: true, can_be_stmt, in_loop_body, .. | ||
134 | }) => (can_be_stmt, in_loop_body), | ||
135 | _ => return, | ||
136 | }; | ||
137 | |||
138 | if in_loop_body { | ||
139 | if can_be_stmt { | ||
133 | add_keyword("continue", "continue;"); | 140 | add_keyword("continue", "continue;"); |
134 | add_keyword("break", "break;"); | 141 | add_keyword("break", "break;"); |
135 | } else { | 142 | } else { |
@@ -138,9 +145,6 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
138 | } | 145 | } |
139 | } | 146 | } |
140 | 147 | ||
141 | if !ctx.is_trivial_path() { | ||
142 | return; | ||
143 | } | ||
144 | let fn_def = match &ctx.function_def { | 148 | let fn_def = match &ctx.function_def { |
145 | Some(it) => it, | 149 | Some(it) => it, |
146 | None => return, | 150 | None => return, |
@@ -148,7 +152,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
148 | 152 | ||
149 | add_keyword( | 153 | add_keyword( |
150 | "return", | 154 | "return", |
151 | match (ctx.can_be_stmt(), fn_def.ret_type().is_some()) { | 155 | match (can_be_stmt, fn_def.ret_type().is_some()) { |
152 | (true, true) => "return $0;", | 156 | (true, true) => "return $0;", |
153 | (true, false) => "return;", | 157 | (true, false) => "return;", |
154 | (false, true) => "return $0", | 158 | (false, true) => "return $0", |
diff --git a/crates/ide_completion/src/completions/macro_in_item_position.rs b/crates/ide_completion/src/completions/macro_in_item_position.rs deleted file mode 100644 index 781b96ff1..000000000 --- a/crates/ide_completion/src/completions/macro_in_item_position.rs +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | //! Completes macro invocations used in item position. | ||
2 | |||
3 | use crate::{CompletionContext, Completions}; | ||
4 | |||
5 | // Ideally this should be removed and moved into `(un)qualified_path` respectively | ||
6 | pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { | ||
7 | // Show only macros in top level. | ||
8 | if !ctx.expects_item() { | ||
9 | return; | ||
10 | } | ||
11 | |||
12 | ctx.scope.process_all_names(&mut |name, res| { | ||
13 | if let hir::ScopeDef::MacroDef(mac) = res { | ||
14 | acc.add_macro(ctx, Some(name.clone()), mac); | ||
15 | } | ||
16 | // FIXME: This should be done in qualified_path/unqualified_path instead? | ||
17 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { | ||
18 | acc.add_resolution(ctx, name, &res); | ||
19 | } | ||
20 | }) | ||
21 | } | ||
22 | |||
23 | #[cfg(test)] | ||
24 | mod tests { | ||
25 | use expect_test::{expect, Expect}; | ||
26 | |||
27 | use crate::{test_utils::completion_list, CompletionKind}; | ||
28 | |||
29 | fn check(ra_fixture: &str, expect: Expect) { | ||
30 | let actual = completion_list(ra_fixture, CompletionKind::Reference); | ||
31 | expect.assert_eq(&actual) | ||
32 | } | ||
33 | |||
34 | #[test] | ||
35 | fn completes_macros_as_item() { | ||
36 | check( | ||
37 | r#" | ||
38 | macro_rules! foo { () => {} } | ||
39 | fn foo() {} | ||
40 | |||
41 | $0 | ||
42 | "#, | ||
43 | expect![[r#" | ||
44 | ma foo!(…) macro_rules! foo | ||
45 | "#]], | ||
46 | ) | ||
47 | } | ||
48 | } | ||
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index c072de7b5..d58745fb4 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs | |||
@@ -7,7 +7,7 @@ use syntax::AstNode; | |||
7 | use crate::{CompletionContext, Completions}; | 7 | use crate::{CompletionContext, Completions}; |
8 | 8 | ||
9 | pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { | 9 | pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { |
10 | if ctx.is_path_disallowed() || ctx.expects_item() { | 10 | if ctx.is_path_disallowed() { |
11 | return; | 11 | return; |
12 | } | 12 | } |
13 | let path = match ctx.path_qual() { | 13 | let path = match ctx.path_qual() { |
@@ -20,7 +20,8 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
20 | None => return, | 20 | None => return, |
21 | }; | 21 | }; |
22 | let context_module = ctx.scope.module(); | 22 | let context_module = ctx.scope.module(); |
23 | if ctx.expects_assoc_item() { | 23 | |
24 | if ctx.expects_item() || ctx.expects_assoc_item() { | ||
24 | if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution { | 25 | if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution { |
25 | let module_scope = module.scope(ctx.db, context_module); | 26 | let module_scope = module.scope(ctx.db, context_module); |
26 | for (name, def) in module_scope { | 27 | for (name, def) in module_scope { |
@@ -631,17 +632,17 @@ impl MyStruct { | |||
631 | "#, | 632 | "#, |
632 | expect![[r##" | 633 | expect![[r##" |
633 | md bar | 634 | md bar |
634 | ma foo! #[macro_export] macro_rules! foo | 635 | ma foo!(…) #[macro_export] macro_rules! foo |
635 | "##]], | 636 | "##]], |
636 | ); | 637 | ); |
637 | } | 638 | } |
638 | 639 | ||
639 | #[test] | 640 | #[test] |
640 | #[ignore] // FIXME doesn't complete anything atm | ||
641 | fn completes_in_item_list() { | 641 | fn completes_in_item_list() { |
642 | check( | 642 | check( |
643 | r#" | 643 | r#" |
644 | struct MyStruct {} | 644 | struct MyStruct {} |
645 | #[macro_export] | ||
645 | macro_rules! foo {} | 646 | macro_rules! foo {} |
646 | mod bar {} | 647 | mod bar {} |
647 | 648 | ||
@@ -649,7 +650,7 @@ crate::$0 | |||
649 | "#, | 650 | "#, |
650 | expect![[r#" | 651 | expect![[r#" |
651 | md bar | 652 | md bar |
652 | ma foo! macro_rules! foo | 653 | ma foo!(…) #[macro_export] macro_rules! foo |
653 | "#]], | 654 | "#]], |
654 | ) | 655 | ) |
655 | } | 656 | } |
diff --git a/crates/ide_completion/src/completions/snippet.rs b/crates/ide_completion/src/completions/snippet.rs index 59a338e7b..b9862de67 100644 --- a/crates/ide_completion/src/completions/snippet.rs +++ b/crates/ide_completion/src/completions/snippet.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | use ide_db::helpers::SnippetCap; | 3 | use ide_db::helpers::SnippetCap; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, | 6 | context::PathCompletionContext, item::Builder, CompletionContext, CompletionItem, |
7 | Completions, | 7 | CompletionItemKind, CompletionKind, Completions, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { | 10 | fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { |
@@ -14,15 +14,21 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) | |||
14 | } | 14 | } |
15 | 15 | ||
16 | pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) { | 16 | pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) { |
17 | if !(ctx.is_trivial_path() && ctx.function_def.is_some()) { | 17 | if ctx.function_def.is_none() { |
18 | return; | 18 | return; |
19 | } | 19 | } |
20 | |||
21 | let can_be_stmt = match ctx.path_context { | ||
22 | Some(PathCompletionContext { is_trivial_path: true, can_be_stmt, .. }) => can_be_stmt, | ||
23 | _ => return, | ||
24 | }; | ||
25 | |||
20 | let cap = match ctx.config.snippet_cap { | 26 | let cap = match ctx.config.snippet_cap { |
21 | Some(it) => it, | 27 | Some(it) => it, |
22 | None => return, | 28 | None => return, |
23 | }; | 29 | }; |
24 | 30 | ||
25 | if ctx.can_be_stmt() { | 31 | if can_be_stmt { |
26 | snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); | 32 | snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); |
27 | snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc); | 33 | snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc); |
28 | } | 34 | } |
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index 968c0254d..a60e5f43c 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs | |||
@@ -34,20 +34,13 @@ | |||
34 | use hir::{self, HasAttrs, HasSource}; | 34 | use hir::{self, HasAttrs, HasSource}; |
35 | use ide_db::{traits::get_missing_assoc_items, SymbolKind}; | 35 | use ide_db::{traits::get_missing_assoc_items, SymbolKind}; |
36 | use syntax::{ | 36 | use syntax::{ |
37 | ast::{self, edit, Impl}, | 37 | ast::{self, edit}, |
38 | display::function_declaration, | 38 | display::function_declaration, |
39 | AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T, | 39 | AstNode, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, T, |
40 | }; | 40 | }; |
41 | use text_edit::TextEdit; | 41 | use text_edit::TextEdit; |
42 | 42 | ||
43 | use crate::{ | 43 | use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; |
44 | CompletionContext, | ||
45 | CompletionItem, | ||
46 | CompletionItemKind, | ||
47 | CompletionKind, | ||
48 | Completions, | ||
49 | // display::function_declaration, | ||
50 | }; | ||
51 | 44 | ||
52 | #[derive(Debug, PartialEq, Eq)] | 45 | #[derive(Debug, PartialEq, Eq)] |
53 | enum ImplCompletionKind { | 46 | enum ImplCompletionKind { |
@@ -58,7 +51,7 @@ enum ImplCompletionKind { | |||
58 | } | 51 | } |
59 | 52 | ||
60 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { | 53 | pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) { |
61 | if let Some((kind, trigger, impl_def)) = completion_match(ctx) { | 54 | if let Some((kind, trigger, impl_def)) = completion_match(ctx.token.clone()) { |
62 | get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item { | 55 | get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item { |
63 | hir::AssocItem::Function(fn_item) | 56 | hir::AssocItem::Function(fn_item) |
64 | if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn => | 57 | if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn => |
@@ -80,8 +73,7 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext | |||
80 | } | 73 | } |
81 | } | 74 | } |
82 | 75 | ||
83 | fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { | 76 | fn completion_match(mut token: SyntaxToken) -> Option<(ImplCompletionKind, SyntaxNode, ast::Impl)> { |
84 | let mut token = ctx.token.clone(); | ||
85 | // For keyword without name like `impl .. { fn $0 }`, the current position is inside | 77 | // For keyword without name like `impl .. { fn $0 }`, the current position is inside |
86 | // the whitespace token, which is outside `FN` syntax node. | 78 | // the whitespace token, which is outside `FN` syntax node. |
87 | // We need to follow the previous token in this case. | 79 | // We need to follow the previous token in this case. |
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index f321ed52b..8b22933e0 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs | |||
@@ -5,26 +5,25 @@ use hir::ScopeDef; | |||
5 | use crate::{CompletionContext, Completions}; | 5 | use crate::{CompletionContext, Completions}; |
6 | 6 | ||
7 | pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { | 7 | pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { |
8 | if !ctx.is_trivial_path() { | 8 | if ctx.is_path_disallowed() || !ctx.is_trivial_path() { |
9 | return; | ||
10 | } | ||
11 | if ctx.is_path_disallowed() || ctx.expects_item() { | ||
12 | return; | 9 | return; |
13 | } | 10 | } |
14 | 11 | ||
15 | if ctx.expects_assoc_item() { | 12 | if ctx.expects_item() || ctx.expects_assoc_item() { |
16 | ctx.scope.process_all_names(&mut |name, def| { | 13 | // only show macros in {Assoc}ItemList |
17 | if let ScopeDef::MacroDef(macro_def) = def { | 14 | ctx.scope.process_all_names(&mut |name, res| { |
18 | acc.add_macro(ctx, Some(name.clone()), macro_def); | 15 | if let hir::ScopeDef::MacroDef(mac) = res { |
16 | acc.add_macro(ctx, Some(name.clone()), mac); | ||
19 | } | 17 | } |
20 | if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { | 18 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { |
21 | acc.add_resolution(ctx, name, &def); | 19 | acc.add_resolution(ctx, name, &res); |
22 | } | 20 | } |
23 | }); | 21 | }); |
24 | return; | 22 | return; |
25 | } | 23 | } |
26 | 24 | ||
27 | if ctx.expects_use_tree() { | 25 | if ctx.expects_use_tree() { |
26 | // only show modules in a fresh UseTree | ||
28 | cov_mark::hit!(only_completes_modules_in_import); | 27 | cov_mark::hit!(only_completes_modules_in_import); |
29 | ctx.scope.process_all_names(&mut |name, res| { | 28 | ctx.scope.process_all_names(&mut |name, res| { |
30 | if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { | 29 | if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { |
@@ -693,12 +692,11 @@ impl MyStruct { | |||
693 | "#, | 692 | "#, |
694 | expect![[r#" | 693 | expect![[r#" |
695 | md bar | 694 | md bar |
696 | ma foo! macro_rules! foo | 695 | ma foo!(…) macro_rules! foo |
697 | "#]], | 696 | "#]], |
698 | ) | 697 | ) |
699 | } | 698 | } |
700 | 699 | ||
701 | // FIXME: The completions here currently come from `macro_in_item_position`, but they shouldn't | ||
702 | #[test] | 700 | #[test] |
703 | fn completes_in_item_list() { | 701 | fn completes_in_item_list() { |
704 | check( | 702 | check( |
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 20e033d31..6177caa12 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -43,6 +43,7 @@ pub(crate) struct PathCompletionContext { | |||
43 | pub(super) can_be_stmt: bool, | 43 | pub(super) can_be_stmt: bool, |
44 | /// `true` if we expect an expression at the cursor position. | 44 | /// `true` if we expect an expression at the cursor position. |
45 | pub(super) is_expr: bool, | 45 | pub(super) is_expr: bool, |
46 | pub(super) in_loop_body: bool, | ||
46 | } | 47 | } |
47 | 48 | ||
48 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | 49 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
@@ -67,14 +68,13 @@ pub(crate) struct CompletionContext<'a> { | |||
67 | pub(super) krate: Option<hir::Crate>, | 68 | pub(super) krate: Option<hir::Crate>, |
68 | pub(super) expected_name: Option<NameOrNameRef>, | 69 | pub(super) expected_name: Option<NameOrNameRef>, |
69 | pub(super) expected_type: Option<Type>, | 70 | pub(super) expected_type: Option<Type>, |
70 | pub(super) name_ref_syntax: Option<ast::NameRef>, | ||
71 | |||
72 | pub(super) use_item_syntax: Option<ast::Use>, | ||
73 | 71 | ||
74 | /// The parent function of the cursor position if it exists. | 72 | /// The parent function of the cursor position if it exists. |
75 | pub(super) function_def: Option<ast::Fn>, | 73 | pub(super) function_def: Option<ast::Fn>, |
76 | /// The parent impl of the cursor position if it exists. | 74 | /// The parent impl of the cursor position if it exists. |
77 | pub(super) impl_def: Option<ast::Impl>, | 75 | pub(super) impl_def: Option<ast::Impl>, |
76 | pub(super) name_ref_syntax: Option<ast::NameRef>, | ||
77 | pub(super) use_item_syntax: Option<ast::Use>, | ||
78 | 78 | ||
79 | // potentially set if we are completing a lifetime | 79 | // potentially set if we are completing a lifetime |
80 | pub(super) lifetime_syntax: Option<ast::Lifetime>, | 80 | pub(super) lifetime_syntax: Option<ast::Lifetime>, |
@@ -89,14 +89,12 @@ pub(crate) struct CompletionContext<'a> { | |||
89 | pub(super) completion_location: Option<ImmediateLocation>, | 89 | pub(super) completion_location: Option<ImmediateLocation>, |
90 | pub(super) prev_sibling: Option<ImmediatePrevSibling>, | 90 | pub(super) prev_sibling: Option<ImmediatePrevSibling>, |
91 | pub(super) attribute_under_caret: Option<ast::Attr>, | 91 | pub(super) attribute_under_caret: Option<ast::Attr>, |
92 | pub(super) previous_token: Option<SyntaxToken>, | ||
92 | 93 | ||
93 | pub(super) path_context: Option<PathCompletionContext>, | 94 | pub(super) path_context: Option<PathCompletionContext>, |
94 | /// FIXME: `ActiveParameter` is string-based, which is very very wrong | ||
95 | pub(super) active_parameter: Option<ActiveParameter>, | 95 | pub(super) active_parameter: Option<ActiveParameter>, |
96 | pub(super) locals: Vec<(String, Local)>, | 96 | pub(super) locals: Vec<(String, Local)>, |
97 | 97 | ||
98 | pub(super) previous_token: Option<SyntaxToken>, | ||
99 | pub(super) in_loop_body: bool, | ||
100 | pub(super) incomplete_let: bool, | 98 | pub(super) incomplete_let: bool, |
101 | 99 | ||
102 | no_completion_required: bool, | 100 | no_completion_required: bool, |
@@ -143,28 +141,27 @@ impl<'a> CompletionContext<'a> { | |||
143 | original_token, | 141 | original_token, |
144 | token, | 142 | token, |
145 | krate, | 143 | krate, |
146 | lifetime_allowed: false, | ||
147 | expected_name: None, | 144 | expected_name: None, |
148 | expected_type: None, | 145 | expected_type: None, |
146 | function_def: None, | ||
147 | impl_def: None, | ||
149 | name_ref_syntax: None, | 148 | name_ref_syntax: None, |
149 | use_item_syntax: None, | ||
150 | lifetime_syntax: None, | 150 | lifetime_syntax: None, |
151 | lifetime_param_syntax: None, | 151 | lifetime_param_syntax: None, |
152 | function_def: None, | 152 | lifetime_allowed: false, |
153 | use_item_syntax: None, | ||
154 | impl_def: None, | ||
155 | active_parameter: ActiveParameter::at(db, position), | ||
156 | is_label_ref: false, | 153 | is_label_ref: false, |
157 | is_param: false, | ||
158 | is_pat_or_const: None, | 154 | is_pat_or_const: None, |
159 | path_context: None, | 155 | is_param: false, |
160 | previous_token: None, | ||
161 | in_loop_body: false, | ||
162 | completion_location: None, | 156 | completion_location: None, |
163 | prev_sibling: None, | 157 | prev_sibling: None, |
164 | no_completion_required: false, | ||
165 | incomplete_let: false, | ||
166 | attribute_under_caret: None, | 158 | attribute_under_caret: None, |
159 | previous_token: None, | ||
160 | path_context: None, | ||
161 | active_parameter: ActiveParameter::at(db, position), | ||
167 | locals, | 162 | locals, |
163 | incomplete_let: false, | ||
164 | no_completion_required: false, | ||
168 | }; | 165 | }; |
169 | 166 | ||
170 | let mut original_file = original_file.syntax().clone(); | 167 | let mut original_file = original_file.syntax().clone(); |
@@ -326,10 +323,6 @@ impl<'a> CompletionContext<'a> { | |||
326 | self.path_context.as_ref().and_then(|it| it.path_qual.as_ref()) | 323 | self.path_context.as_ref().and_then(|it| it.path_qual.as_ref()) |
327 | } | 324 | } |
328 | 325 | ||
329 | pub(crate) fn can_be_stmt(&self) -> bool { | ||
330 | self.path_context.as_ref().map_or(false, |it| it.can_be_stmt) | ||
331 | } | ||
332 | |||
333 | fn fill_impl_def(&mut self) { | 326 | fn fill_impl_def(&mut self) { |
334 | self.impl_def = self | 327 | self.impl_def = self |
335 | .sema | 328 | .sema |
@@ -455,7 +448,6 @@ impl<'a> CompletionContext<'a> { | |||
455 | let for_is_prev2 = for_is_prev2(syntax_element.clone()); | 448 | let for_is_prev2 = for_is_prev2(syntax_element.clone()); |
456 | (fn_is_prev && !inside_impl_trait_block) || for_is_prev2 | 449 | (fn_is_prev && !inside_impl_trait_block) || for_is_prev2 |
457 | }; | 450 | }; |
458 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); | ||
459 | 451 | ||
460 | self.incomplete_let = | 452 | self.incomplete_let = |
461 | syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| { | 453 | syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| { |
@@ -563,10 +555,6 @@ impl<'a> CompletionContext<'a> { | |||
563 | self.name_ref_syntax = | 555 | self.name_ref_syntax = |
564 | find_node_at_offset(original_file, name_ref.syntax().text_range().start()); | 556 | find_node_at_offset(original_file, name_ref.syntax().text_range().start()); |
565 | 557 | ||
566 | if matches!(self.completion_location, Some(ImmediateLocation::ItemList)) { | ||
567 | return; | ||
568 | } | ||
569 | |||
570 | self.use_item_syntax = | 558 | self.use_item_syntax = |
571 | self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast); | 559 | self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast); |
572 | 560 | ||
@@ -590,14 +578,16 @@ impl<'a> CompletionContext<'a> { | |||
590 | is_path_type: false, | 578 | is_path_type: false, |
591 | can_be_stmt: false, | 579 | can_be_stmt: false, |
592 | is_expr: false, | 580 | is_expr: false, |
581 | in_loop_body: false, | ||
593 | }); | 582 | }); |
583 | path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax()); | ||
594 | let path = segment.parent_path(); | 584 | let path = segment.parent_path(); |
595 | 585 | ||
596 | if let Some(p) = path.syntax().parent() { | 586 | if let Some(p) = path.syntax().parent() { |
597 | path_ctx.call_kind = match_ast! { | 587 | path_ctx.call_kind = match_ast! { |
598 | match p { | 588 | match p { |
599 | ast::PathExpr(it) => it.syntax().parent().and_then(ast::CallExpr::cast).map(|_| CallKind::Expr), | 589 | ast::PathExpr(it) => it.syntax().parent().and_then(ast::CallExpr::cast).map(|_| CallKind::Expr), |
600 | ast::MacroCall(_it) => Some(CallKind::Mac), | 590 | ast::MacroCall(it) => it.excl_token().and(Some(CallKind::Mac)), |
601 | ast::TupleStructPat(_it) => Some(CallKind::Pat), | 591 | ast::TupleStructPat(_it) => Some(CallKind::Pat), |
602 | _ => None | 592 | _ => None |
603 | } | 593 | } |
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs index 6fb38f50d..18983aa01 100644 --- a/crates/ide_completion/src/lib.rs +++ b/crates/ide_completion/src/lib.rs | |||
@@ -158,7 +158,6 @@ pub fn completions( | |||
158 | completions::record::complete_record(&mut acc, &ctx); | 158 | completions::record::complete_record(&mut acc, &ctx); |
159 | completions::pattern::complete_pattern(&mut acc, &ctx); | 159 | completions::pattern::complete_pattern(&mut acc, &ctx); |
160 | completions::postfix::complete_postfix(&mut acc, &ctx); | 160 | completions::postfix::complete_postfix(&mut acc, &ctx); |
161 | completions::macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx); | ||
162 | completions::trait_impl::complete_trait_impl(&mut acc, &ctx); | 161 | completions::trait_impl::complete_trait_impl(&mut acc, &ctx); |
163 | completions::mod_::complete_mod(&mut acc, &ctx); | 162 | completions::mod_::complete_mod(&mut acc, &ctx); |
164 | completions::flyimport::import_on_the_fly(&mut acc, &ctx); | 163 | completions::flyimport::import_on_the_fly(&mut acc, &ctx); |
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs index 251d76fe9..ee87bf461 100644 --- a/crates/ide_completion/src/patterns.rs +++ b/crates/ide_completion/src/patterns.rs | |||
@@ -272,9 +272,8 @@ fn test_for_is_prev2() { | |||
272 | check_pattern_is_applicable(r"for i i$0", for_is_prev2); | 272 | check_pattern_is_applicable(r"for i i$0", for_is_prev2); |
273 | } | 273 | } |
274 | 274 | ||
275 | pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { | 275 | pub(crate) fn is_in_loop_body(node: &SyntaxNode) -> bool { |
276 | element | 276 | node.ancestors() |
277 | .ancestors() | ||
278 | .take_while(|it| it.kind() != FN && it.kind() != CLOSURE_EXPR) | 277 | .take_while(|it| it.kind() != FN && it.kind() != CLOSURE_EXPR) |
279 | .find_map(|it| { | 278 | .find_map(|it| { |
280 | let loop_body = match_ast! { | 279 | let loop_body = match_ast! { |
@@ -285,7 +284,7 @@ pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { | |||
285 | _ => None, | 284 | _ => None, |
286 | } | 285 | } |
287 | }; | 286 | }; |
288 | loop_body.filter(|it| it.syntax().text_range().contains_range(element.text_range())) | 287 | loop_body.filter(|it| it.syntax().text_range().contains_range(node.text_range())) |
289 | }) | 288 | }) |
290 | .is_some() | 289 | .is_some() |
291 | } | 290 | } |