Skip to content

Commit 1878fbe

Browse files
bors[bot]slyngbaek
andauthored
Merge #3541
3541: Completition for type name? #3418 r=matklad a=slyngbaek Iterate through TupleStructPat's until a MatchArm if one exists. Store in a new is_pat_bind_and_path bool and allow the `complete_scope` to find matches. Added some tests to ensure it works in simple and nested cases. Co-authored-by: Steffen Lyngbaek <[email protected]>
2 parents 1ba03c6 + ec24c09 commit 1878fbe

File tree

3 files changed

+143
-3
lines changed

3 files changed

+143
-3
lines changed

crates/ra_ide/src/completion/complete_pattern.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ mod tests {
5555
);
5656
assert_debug_snapshot!(completions, @r###"
5757
[
58+
CompletionItem {
59+
label: "Bar",
60+
source_range: [246; 246),
61+
delete: [246; 246),
62+
insert: "Bar",
63+
kind: Struct,
64+
},
65+
CompletionItem {
66+
label: "E",
67+
source_range: [246; 246),
68+
delete: [246; 246),
69+
insert: "E",
70+
kind: Enum,
71+
},
5872
CompletionItem {
5973
label: "E",
6074
source_range: [246; 246),
@@ -69,6 +83,20 @@ mod tests {
6983
insert: "X",
7084
kind: EnumVariant,
7185
},
86+
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+
},
72100
CompletionItem {
73101
label: "Z",
74102
source_range: [246; 246),
@@ -83,6 +111,13 @@ mod tests {
83111
insert: "m",
84112
kind: Module,
85113
},
114+
CompletionItem {
115+
label: "m",
116+
source_range: [246; 246),
117+
delete: [246; 246),
118+
insert: "m",
119+
kind: Module,
120+
},
86121
]
87122
"###);
88123
}
@@ -110,6 +145,21 @@ mod tests {
110145
insert: "E",
111146
kind: Enum,
112147
},
148+
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!",
157+
source_range: [151; 151),
158+
delete: [151; 151),
159+
insert: "m!($0)",
160+
kind: Macro,
161+
detail: "macro_rules! m",
162+
},
113163
]
114164
"###);
115165
}

crates/ra_ide/src/completion/complete_scope.rs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
//! Completion of names from the current scope, e.g. locals and imported items.
22
33
use crate::completion::{CompletionContext, Completions};
4+
use hir::{ModuleDef, ScopeDef};
45

56
pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
6-
if !ctx.is_trivial_path {
7+
if !ctx.is_trivial_path && !ctx.is_pat_binding_and_path {
78
return;
89
}
910

10-
ctx.scope().process_all_names(&mut |name, res| acc.add_resolution(ctx, name.to_string(), &res));
11+
ctx.scope().process_all_names(&mut |name, res| match (ctx.is_pat_binding_and_path, &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+
});
1117
}
1218

1319
#[cfg(test)]
@@ -20,6 +26,79 @@ mod tests {
2026
do_completion(ra_fixture, CompletionKind::Reference)
2127
}
2228

29+
#[test]
30+
fn bind_pat_and_path_ignore_at() {
31+
assert_debug_snapshot!(
32+
do_reference_completion(
33+
r"
34+
enum Enum {
35+
A,
36+
B,
37+
}
38+
fn quux(x: Option<Enum>) {
39+
match x {
40+
None => (),
41+
Some(en<|> @ Enum::A) => (),
42+
}
43+
}
44+
"
45+
),
46+
@r###"[]"###
47+
);
48+
}
49+
50+
#[test]
51+
fn bind_pat_and_path_ignore_ref() {
52+
assert_debug_snapshot!(
53+
do_reference_completion(
54+
r"
55+
enum Enum {
56+
A,
57+
B,
58+
}
59+
fn quux(x: Option<Enum>) {
60+
match x {
61+
None => (),
62+
Some(ref en<|>) => (),
63+
}
64+
}
65+
"
66+
),
67+
@r###"[]"###
68+
);
69+
}
70+
71+
#[test]
72+
fn bind_pat_and_path() {
73+
assert_debug_snapshot!(
74+
do_reference_completion(
75+
r"
76+
enum Enum {
77+
A,
78+
B,
79+
}
80+
fn quux(x: Option<Enum>) {
81+
match x {
82+
None => (),
83+
Some(En<|>) => (),
84+
}
85+
}
86+
"
87+
),
88+
@r###"
89+
[
90+
CompletionItem {
91+
label: "Enum",
92+
source_range: [231; 233),
93+
delete: [231; 233),
94+
insert: "Enum",
95+
kind: Enum,
96+
},
97+
]
98+
"###
99+
);
100+
}
101+
23102
#[test]
24103
fn completes_bindings_from_let() {
25104
assert_debug_snapshot!(

crates/ra_ide/src/completion/completion_context.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub(crate) struct CompletionContext<'a> {
3636
/// If a name-binding or reference to a const in a pattern.
3737
/// Irrefutable patterns (like let) are excluded.
3838
pub(super) is_pat_binding: 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,
3942
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
4043
pub(super) is_trivial_path: bool,
4144
/// If not a trivial path, the prefix (qualifier).
@@ -95,6 +98,7 @@ impl<'a> CompletionContext<'a> {
9598
impl_def: None,
9699
is_param: false,
97100
is_pat_binding: false,
101+
is_pat_binding_and_path: false,
98102
is_trivial_path: false,
99103
path_prefix: None,
100104
after_if: false,
@@ -188,10 +192,17 @@ impl<'a> CompletionContext<'a> {
188192
if let Some(bind_pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) {
189193
let parent = bind_pat.syntax().parent();
190194
if parent.clone().and_then(ast::MatchArm::cast).is_some()
191-
|| parent.and_then(ast::Condition::cast).is_some()
195+
|| parent.clone().and_then(ast::Condition::cast).is_some()
192196
{
193197
self.is_pat_binding = true;
194198
}
199+
200+
if parent.and_then(ast::RecordFieldPatList::cast).is_none()
201+
&& bind_pat.pat().is_none()
202+
&& !bind_pat.is_ref()
203+
{
204+
self.is_pat_binding_and_path = true;
205+
}
195206
}
196207
if is_node::<ast::Param>(name.syntax()) {
197208
self.is_param = true;

0 commit comments

Comments
 (0)