aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide/src/completion/complete_pattern.rs57
-rw-r--r--crates/ra_ide/src/completion/complete_scope.rs10
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs31
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs3
4 files changed, 31 insertions, 70 deletions
diff --git a/crates/ra_ide/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs
index bc8fade6f..1c8b50eec 100644
--- a/crates/ra_ide/src/completion/complete_pattern.rs
+++ b/crates/ra_ide/src/completion/complete_pattern.rs
@@ -4,23 +4,25 @@ use crate::completion::{CompletionContext, Completions};
4 4
5/// Completes constats and paths in patterns. 5/// Completes constats and paths in patterns.
6pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { 6pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
7 if !ctx.is_pat_binding { 7 if !ctx.is_pat_binding_or_const {
8 return; 8 return;
9 } 9 }
10 // FIXME: ideally, we should look at the type we are matching against and 10 // FIXME: ideally, we should look at the type we are matching against and
11 // suggest variants + auto-imports 11 // suggest variants + auto-imports
12 ctx.scope().process_all_names(&mut |name, res| { 12 ctx.scope().process_all_names(&mut |name, res| {
13 let def = match &res { 13 match &res {
14 hir::ScopeDef::ModuleDef(def) => def, 14 hir::ScopeDef::ModuleDef(def) => match def {
15 hir::ModuleDef::Adt(hir::Adt::Enum(..))
16 | hir::ModuleDef::Adt(hir::Adt::Struct(..))
17 | hir::ModuleDef::EnumVariant(..)
18 | hir::ModuleDef::Const(..)
19 | hir::ModuleDef::Module(..) => (),
20 _ => return,
21 },
22 hir::ScopeDef::MacroDef(_) => (),
15 _ => return, 23 _ => return,
16 }; 24 };
17 match def { 25
18 hir::ModuleDef::Adt(hir::Adt::Enum(..))
19 | hir::ModuleDef::EnumVariant(..)
20 | hir::ModuleDef::Const(..)
21 | hir::ModuleDef::Module(..) => (),
22 _ => return,
23 }
24 acc.add_resolution(ctx, name.to_string(), &res) 26 acc.add_resolution(ctx, name.to_string(), &res)
25 }); 27 });
26} 28}
@@ -70,13 +72,6 @@ mod tests {
70 kind: Enum, 72 kind: Enum,
71 }, 73 },
72 CompletionItem { 74 CompletionItem {
73 label: "E",
74 source_range: [246; 246),
75 delete: [246; 246),
76 insert: "E",
77 kind: Enum,
78 },
79 CompletionItem {
80 label: "X", 75 label: "X",
81 source_range: [246; 246), 76 source_range: [246; 246),
82 delete: [246; 246), 77 delete: [246; 246),
@@ -84,20 +79,6 @@ mod tests {
84 kind: EnumVariant, 79 kind: EnumVariant,
85 }, 80 },
86 CompletionItem { 81 CompletionItem {
87 label: "X",
88 source_range: [246; 246),
89 delete: [246; 246),
90 insert: "X",
91 kind: EnumVariant,
92 },
93 CompletionItem {
94 label: "Z",
95 source_range: [246; 246),
96 delete: [246; 246),
97 insert: "Z",
98 kind: Const,
99 },
100 CompletionItem {
101 label: "Z", 82 label: "Z",
102 source_range: [246; 246), 83 source_range: [246; 246),
103 delete: [246; 246), 84 delete: [246; 246),
@@ -111,13 +92,6 @@ mod tests {
111 insert: "m", 92 insert: "m",
112 kind: Module, 93 kind: Module,
113 }, 94 },
114 CompletionItem {
115 label: "m",
116 source_range: [246; 246),
117 delete: [246; 246),
118 insert: "m",
119 kind: Module,
120 },
121 ] 95 ]
122 "###); 96 "###);
123 } 97 }
@@ -146,13 +120,6 @@ mod tests {
146 kind: Enum, 120 kind: Enum,
147 }, 121 },
148 CompletionItem { 122 CompletionItem {
149 label: "E",
150 source_range: [151; 151),
151 delete: [151; 151),
152 insert: "E",
153 kind: Enum,
154 },
155 CompletionItem {
156 label: "m!", 123 label: "m!",
157 source_range: [151; 151), 124 source_range: [151; 151),
158 delete: [151; 151), 125 delete: [151; 151),
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs
index 2ca552733..665597e4c 100644
--- a/crates/ra_ide/src/completion/complete_scope.rs
+++ b/crates/ra_ide/src/completion/complete_scope.rs
@@ -1,19 +1,13 @@
1//! Completion of names from the current scope, e.g. locals and imported items. 1//! Completion of names from the current scope, e.g. locals and imported items.
2 2
3use crate::completion::{CompletionContext, Completions}; 3use crate::completion::{CompletionContext, Completions};
4use hir::{ModuleDef, ScopeDef};
5 4
6pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { 5pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
7 if !ctx.is_trivial_path && !ctx.is_pat_binding_and_path { 6 if !(ctx.is_trivial_path && !ctx.is_pat_binding_or_const) {
8 return; 7 return;
9 } 8 }
10 9
11 ctx.scope().process_all_names(&mut |name, res| match (ctx.is_pat_binding_and_path, &res) { 10 ctx.scope().process_all_names(&mut |name, res| acc.add_resolution(ctx, name.to_string(), &res));
12 (true, ScopeDef::ModuleDef(ModuleDef::Function(..))) => (),
13 (true, ScopeDef::ModuleDef(ModuleDef::Static(..))) => (),
14 (true, ScopeDef::Local(..)) => (),
15 _ => acc.add_resolution(ctx, name.to_string(), &res),
16 });
17} 11}
18 12
19#[cfg(test)] 13#[cfg(test)]
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index fdc0da2c5..b8213d62f 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -35,10 +35,7 @@ pub(crate) struct CompletionContext<'a> {
35 pub(super) is_param: bool, 35 pub(super) is_param: bool,
36 /// If a name-binding or reference to a const in a pattern. 36 /// If a name-binding or reference to a const in a pattern.
37 /// Irrefutable patterns (like let) are excluded. 37 /// Irrefutable patterns (like let) are excluded.
38 pub(super) is_pat_binding: bool, 38 pub(super) is_pat_binding_or_const: bool,
39 // A bind battern which may also be part of a path.
40 // if let Some(En<|>) = Some(Enum::A)
41 pub(super) is_pat_binding_and_path: bool,
42 /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path. 39 /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
43 pub(super) is_trivial_path: bool, 40 pub(super) is_trivial_path: bool,
44 /// If not a trivial path, the prefix (qualifier). 41 /// If not a trivial path, the prefix (qualifier).
@@ -97,8 +94,7 @@ impl<'a> CompletionContext<'a> {
97 record_lit_pat: None, 94 record_lit_pat: None,
98 impl_def: None, 95 impl_def: None,
99 is_param: false, 96 is_param: false,
100 is_pat_binding: false, 97 is_pat_binding_or_const: false,
101 is_pat_binding_and_path: false,
102 is_trivial_path: false, 98 is_trivial_path: false,
103 path_prefix: None, 99 path_prefix: None,
104 after_if: false, 100 after_if: false,
@@ -190,18 +186,19 @@ impl<'a> CompletionContext<'a> {
190 // suggest declaration names, see `CompletionKind::Magic`. 186 // suggest declaration names, see `CompletionKind::Magic`.
191 if let Some(name) = find_node_at_offset::<ast::Name>(&file_with_fake_ident, offset) { 187 if let Some(name) = find_node_at_offset::<ast::Name>(&file_with_fake_ident, offset) {
192 if let Some(bind_pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) { 188 if let Some(bind_pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) {
193 let parent = bind_pat.syntax().parent(); 189 self.is_pat_binding_or_const = true;
194 if parent.clone().and_then(ast::MatchArm::cast).is_some() 190 if bind_pat.has_at() || bind_pat.is_ref() || bind_pat.is_mutable() {
195 || parent.clone().and_then(ast::Condition::cast).is_some() 191 self.is_pat_binding_or_const = false;
196 {
197 self.is_pat_binding = true;
198 } 192 }
199 193 if bind_pat.syntax().parent().and_then(ast::RecordFieldPatList::cast).is_some() {
200 if parent.and_then(ast::RecordFieldPatList::cast).is_none() 194 self.is_pat_binding_or_const = false;
201 && bind_pat.pat().is_none() 195 }
202 && !bind_pat.is_ref() 196 if let Some(let_stmt) = bind_pat.syntax().ancestors().find_map(ast::LetStmt::cast) {
203 { 197 if let Some(pat) = let_stmt.pat() {
204 self.is_pat_binding_and_path = true; 198 if bind_pat.syntax().text_range().is_subrange(&pat.syntax().text_range()) {
199 self.is_pat_binding_or_const = false;
200 }
201 }
205 } 202 }
206 } 203 }
207 if is_node::<ast::Param>(name.syntax()) { 204 if is_node::<ast::Param>(name.syntax()) {
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 392731dac..bf7d137be 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -325,6 +325,9 @@ impl ast::BindPat {
325 pub fn is_ref(&self) -> bool { 325 pub fn is_ref(&self) -> bool {
326 self.syntax().children_with_tokens().any(|n| n.kind() == T![ref]) 326 self.syntax().children_with_tokens().any(|n| n.kind() == T![ref])
327 } 327 }
328 pub fn has_at(&self) -> bool {
329 self.syntax().children_with_tokens().any(|it| it.kind() == T![@])
330 }
328} 331}
329 332
330pub struct SlicePatComponents { 333pub struct SlicePatComponents {