aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-05-28 01:40:40 +0100
committerLukas Wirth <[email protected]>2021-05-28 01:42:47 +0100
commit9e71dd9799879fc9070f8717f8711fba5dae490a (patch)
treec95abc3bdf10e2bc1f60bfa6e6b12ebb03760472 /crates/ide_completion
parent01bfc5f5c0cf6b73c26d006802016c9b02066f94 (diff)
Only complete modules in empty use-statements
Diffstat (limited to 'crates/ide_completion')
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs30
-rw-r--r--crates/ide_completion/src/context.rs4
-rw-r--r--crates/ide_completion/src/patterns.rs7
3 files changed, 27 insertions, 14 deletions
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index c901b358b..ede07f605 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -1,7 +1,6 @@
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 hir::ScopeDef; 3use hir::ScopeDef;
4use syntax::AstNode;
5 4
6use crate::{CompletionContext, Completions}; 5use crate::{CompletionContext, Completions};
7 6
@@ -24,6 +23,15 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
24 return; 23 return;
25 } 24 }
26 25
26 if ctx.expects_use_tree() {
27 cov_mark::hit!(only_completes_modules_in_import);
28 ctx.scope.process_all_names(&mut |name, res| {
29 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
30 acc.add_resolution(ctx, name.to_string(), &res);
31 }
32 });
33 return;
34 }
27 if let Some(hir::Adt::Enum(e)) = 35 if let Some(hir::Adt::Enum(e)) =
28 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) 36 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
29 { 37 {
@@ -37,14 +45,6 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
37 cov_mark::hit!(skip_lifetime_completion); 45 cov_mark::hit!(skip_lifetime_completion);
38 return; 46 return;
39 } 47 }
40 if ctx.use_item_syntax.is_some() {
41 if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
42 if name_ref.syntax().text() == name.to_string().as_str() {
43 cov_mark::hit!(self_fulfilling_completion);
44 return;
45 }
46 }
47 }
48 acc.add_resolution(ctx, name.to_string(), &res); 48 acc.add_resolution(ctx, name.to_string(), &res);
49 }); 49 });
50} 50}
@@ -68,15 +68,17 @@ mod tests {
68 } 68 }
69 69
70 #[test] 70 #[test]
71 fn self_fulfilling_completion() { 71 fn only_completes_modules_in_import() {
72 cov_mark::check!(self_fulfilling_completion); 72 cov_mark::check!(only_completes_modules_in_import);
73 check( 73 check(
74 r#" 74 r#"
75use foo$0 75use f$0
76use std::collections; 76
77struct Foo;
78mod foo {}
77"#, 79"#,
78 expect![[r#" 80 expect![[r#"
79 ?? collections 81 md foo
80 "#]], 82 "#]],
81 ); 83 );
82 } 84 }
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index fbef54408..923e35dbb 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -276,6 +276,10 @@ impl<'a> CompletionContext<'a> {
276 ) 276 )
277 } 277 }
278 278
279 pub(crate) fn expects_use_tree(&self) -> bool {
280 matches!(self.completion_location, Some(ImmediateLocation::Use))
281 }
282
279 pub(crate) fn expects_non_trait_assoc_item(&self) -> bool { 283 pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
280 matches!(self.completion_location, Some(ImmediateLocation::Impl)) 284 matches!(self.completion_location, Some(ImmediateLocation::Impl))
281 } 285 }
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs
index 19e42ba43..7bae7d12c 100644
--- a/crates/ide_completion/src/patterns.rs
+++ b/crates/ide_completion/src/patterns.rs
@@ -14,6 +14,7 @@ use crate::test_utils::{check_pattern_is_applicable, check_pattern_is_not_applic
14/// Direct parent container of the cursor position 14/// Direct parent container of the cursor position
15#[derive(Copy, Clone, Debug, PartialEq, Eq)] 15#[derive(Copy, Clone, Debug, PartialEq, Eq)]
16pub(crate) enum ImmediateLocation { 16pub(crate) enum ImmediateLocation {
17 Use,
17 Impl, 18 Impl,
18 Trait, 19 Trait,
19 RecordField, 20 RecordField,
@@ -58,6 +59,7 @@ pub(crate) fn determine_location(tok: SyntaxToken) -> Option<ImmediateLocation>
58 let res = match_ast! { 59 let res = match_ast! {
59 match parent { 60 match parent {
60 ast::IdentPat(_it) => ImmediateLocation::IdentPat, 61 ast::IdentPat(_it) => ImmediateLocation::IdentPat,
62 ast::Use(_it) => ImmediateLocation::Use,
61 ast::BlockExpr(_it) => ImmediateLocation::BlockExpr, 63 ast::BlockExpr(_it) => ImmediateLocation::BlockExpr,
62 ast::SourceFile(_it) => ImmediateLocation::ItemList, 64 ast::SourceFile(_it) => ImmediateLocation::ItemList,
63 ast::ItemList(_it) => ImmediateLocation::ItemList, 65 ast::ItemList(_it) => ImmediateLocation::ItemList,
@@ -88,6 +90,11 @@ fn test_has_trait_parent() {
88} 90}
89 91
90#[test] 92#[test]
93fn test_has_use_parent() {
94 check_location(r"use f$0", ImmediateLocation::Use);
95}
96
97#[test]
91fn test_has_impl_parent() { 98fn test_has_impl_parent() {
92 check_location(r"impl A { f$0 }", ImmediateLocation::Impl); 99 check_location(r"impl A { f$0 }", ImmediateLocation::Impl);
93} 100}