- Exclude Local Scope for BindPats

- Exclude BindPats with @ or ref
- Remove outdated test and add one testing for ref
This commit is contained in:
Steffen Lyngbaek 2020-03-18 00:46:42 -07:00
parent b6d6277362
commit 6941a7faba
2 changed files with 16 additions and 58 deletions

View File

@ -1,13 +1,17 @@
//! Completion of names from the current scope, e.g. locals and imported items. //! Completion of names from the current scope, e.g. locals and imported items.
use crate::completion::{CompletionContext, Completions}; use crate::completion::{CompletionContext, Completions};
use hir::ScopeDef;
pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
if !ctx.is_trivial_path && !ctx.is_pat_binding_and_path { if !ctx.is_trivial_path && !ctx.is_pat_binding_and_path {
return; return;
} }
ctx.scope().process_all_names(&mut |name, res| acc.add_resolution(ctx, name.to_string(), &res)); ctx.scope().process_all_names(&mut |name, res| match (ctx.is_pat_binding_and_path, &res) {
(true, ScopeDef::Local(..)) => {}
_ => acc.add_resolution(ctx, name.to_string(), &res),
});
} }
#[cfg(test)] #[cfg(test)]
@ -21,53 +25,23 @@ mod tests {
} }
#[test] #[test]
fn nested_bind_pat_and_path() { fn bind_pat_and_path_ignore_ref() {
assert_debug_snapshot!( assert_debug_snapshot!(
do_reference_completion( do_reference_completion(
r" r"
enum First { enum Enum {
A, A,
B, B,
} }
enum Second { fn quux(x: Option<Enum>) {
A(First),
B(First),
}
fn quux(x: Option<Option<Second>>>) {
match x { match x {
None => (), None => (),
Some(Some(Second(Fi<|>))) => (), Some(ref en<|>) => (),
} }
} }
" "
), ),
@r###" @r###"[]"###
[
CompletionItem {
label: "First",
source_range: [363; 365),
delete: [363; 365),
insert: "First",
kind: Enum,
},
CompletionItem {
label: "Second",
source_range: [363; 365),
delete: [363; 365),
insert: "Second",
kind: Enum,
},
CompletionItem {
label: "quux(…)",
source_range: [363; 365),
delete: [363; 365),
insert: "quux(${1:x})$0",
kind: Function,
lookup: "quux",
detail: "fn quux(x: Option<Option<Second>>)",
},
]
"###
); );
} }
@ -83,7 +57,7 @@ mod tests {
fn quux(x: Option<Enum>) { fn quux(x: Option<Enum>) {
match x { match x {
None => (), None => (),
Some(en<|>) => (), Some(En<|>) => (),
} }
} }
" "
@ -97,13 +71,6 @@ mod tests {
insert: "Enum", insert: "Enum",
kind: Enum, kind: Enum,
}, },
CompletionItem {
label: "None",
source_range: [231; 233),
delete: [231; 233),
insert: "None",
kind: Binding,
},
CompletionItem { CompletionItem {
label: "quux(…)", label: "quux(…)",
source_range: [231; 233), source_range: [231; 233),
@ -112,13 +79,7 @@ mod tests {
kind: Function, kind: Function,
lookup: "quux", lookup: "quux",
detail: "fn quux(x: Option<Enum>)", detail: "fn quux(x: Option<Enum>)",
}, trigger_call_info: true,
CompletionItem {
label: "x",
source_range: [231; 233),
delete: [231; 233),
insert: "x",
kind: Binding,
}, },
] ]
"### "###

View File

@ -190,19 +190,16 @@ impl<'a> CompletionContext<'a> {
// suggest declaration names, see `CompletionKind::Magic`. // suggest declaration names, see `CompletionKind::Magic`.
if let Some(name) = find_node_at_offset::<ast::Name>(&file_with_fake_ident, offset) { if let Some(name) = find_node_at_offset::<ast::Name>(&file_with_fake_ident, offset) {
if let Some(bind_pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) { if let Some(bind_pat) = name.syntax().ancestors().find_map(ast::BindPat::cast) {
let mut parent = bind_pat.syntax().parent(); let parent = bind_pat.syntax().parent();
if parent.clone().and_then(ast::MatchArm::cast).is_some() if parent.clone().and_then(ast::MatchArm::cast).is_some()
|| parent.clone().and_then(ast::Condition::cast).is_some() || parent.clone().and_then(ast::Condition::cast).is_some()
{ {
self.is_pat_binding = true; self.is_pat_binding = true;
} }
while let Some(_) = parent.clone().and_then(ast::TupleStructPat::cast) { let bind_pat_string = bind_pat.syntax().to_string();
parent = parent.and_then(|p| p.parent()); if !bind_pat_string.contains("ref ") && !bind_pat_string.contains(" @ ") {
if parent.clone().and_then(ast::MatchArm::cast).is_some() { self.is_pat_binding_and_path = true;
self.is_pat_binding_and_path = true;
break;
}
} }
} }
if is_node::<ast::Param>(name.syntax()) { if is_node::<ast::Param>(name.syntax()) {