aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/completion
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-12-21 20:04:56 +0000
committerAleksey Kladov <[email protected]>2018-12-21 20:04:56 +0000
commit2136e75c0bce090d104bb5b5006e48e42fb22a0a (patch)
treed17fa5832a8e04f925f9d3b62c3c2bf23a2de714 /crates/ra_analysis/src/completion
parentcbe67339df2bbcb17e12ad74e8b8cd53baffb9f7 (diff)
move path completion to a separate component
Diffstat (limited to 'crates/ra_analysis/src/completion')
-rw-r--r--crates/ra_analysis/src/completion/complete_path.rs95
-rw-r--r--crates/ra_analysis/src/completion/reference_completion.rs33
2 files changed, 98 insertions, 30 deletions
diff --git a/crates/ra_analysis/src/completion/complete_path.rs b/crates/ra_analysis/src/completion/complete_path.rs
new file mode 100644
index 000000000..d04503e46
--- /dev/null
+++ b/crates/ra_analysis/src/completion/complete_path.rs
@@ -0,0 +1,95 @@
1use crate::{
2 completion::{CompletionItem, Completions, CompletionKind::*, SyntaxContext},
3 Cancelable,
4};
5
6pub(super) fn complete_path(acc: &mut Completions, ctx: &SyntaxContext) -> Cancelable<()> {
7 let (path, module) = match (&ctx.path_prefix, &ctx.module) {
8 (Some(path), Some(module)) => (path.clone(), module),
9 _ => return Ok(()),
10 };
11 let def_id = match module.resolve_path(ctx.db, path)? {
12 None => return Ok(()),
13 Some(it) => it,
14 };
15 let target_module = match def_id.resolve(ctx.db)? {
16 hir::Def::Module(it) => it,
17 _ => return Ok(()),
18 };
19 let module_scope = target_module.scope(ctx.db)?;
20 module_scope.entries().for_each(|(name, _res)| {
21 CompletionItem::new(name.to_string())
22 .kind(Reference)
23 .add_to(acc)
24 });
25 Ok(())
26}
27
28#[cfg(test)]
29mod tests {
30 use crate::completion::{CompletionKind, check_completion};
31
32 fn check_reference_completion(code: &str, expected_completions: &str) {
33 check_completion(code, expected_completions, CompletionKind::Reference);
34 }
35
36 #[test]
37 fn completes_use_item_starting_with_self() {
38 check_reference_completion(
39 r"
40 use self::m::<|>;
41
42 mod m {
43 struct Bar;
44 }
45 ",
46 "Bar",
47 );
48 }
49
50 #[test]
51 fn completes_use_item_starting_with_crate() {
52 check_reference_completion(
53 "
54 //- /lib.rs
55 mod foo;
56 struct Spam;
57 //- /foo.rs
58 use crate::Sp<|>
59 ",
60 "Spam;foo",
61 );
62 }
63
64 #[test]
65 fn completes_nested_use_tree() {
66 check_reference_completion(
67 "
68 //- /lib.rs
69 mod foo;
70 struct Spam;
71 //- /foo.rs
72 use crate::{Sp<|>};
73 ",
74 "Spam;foo",
75 );
76 }
77
78 #[test]
79 fn completes_deeply_nested_use_tree() {
80 check_reference_completion(
81 "
82 //- /lib.rs
83 mod foo;
84 pub mod bar {
85 pub mod baz {
86 pub struct Spam;
87 }
88 }
89 //- /foo.rs
90 use crate::{bar::{baz::Sp<|>}};
91 ",
92 "Spam",
93 );
94 }
95}
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs
index 46d381927..459ed8f6f 100644
--- a/crates/ra_analysis/src/completion/reference_completion.rs
+++ b/crates/ra_analysis/src/completion/reference_completion.rs
@@ -1,4 +1,4 @@
1use rustc_hash::{FxHashSet}; 1use rustc_hash::FxHashSet;
2use ra_syntax::{ 2use ra_syntax::{
3 SourceFileNode, AstNode, 3 SourceFileNode, AstNode,
4 ast, 4 ast,
@@ -6,7 +6,7 @@ use ra_syntax::{
6}; 6};
7use hir::{ 7use hir::{
8 self, 8 self,
9 FnScopes, Def, Path 9 FnScopes, Path
10}; 10};
11 11
12use crate::{ 12use crate::{
@@ -53,7 +53,7 @@ pub(super) fn completions(
53 .add_to(acc) 53 .add_to(acc)
54 }); 54 });
55 } 55 }
56 NameRefKind::Path(path) => complete_path(acc, db, module, path)?, 56 NameRefKind::Path(_) => (),
57 NameRefKind::BareIdentInMod => (), 57 NameRefKind::BareIdentInMod => (),
58 } 58 }
59 Ok(()) 59 Ok(())
@@ -121,33 +121,6 @@ fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Completions)
121 } 121 }
122} 122}
123 123
124fn complete_path(
125 acc: &mut Completions,
126 db: &RootDatabase,
127 module: &hir::Module,
128 mut path: Path,
129) -> Cancelable<()> {
130 if path.segments.is_empty() {
131 return Ok(());
132 }
133 path.segments.pop();
134 let def_id = match module.resolve_path(db, path)? {
135 None => return Ok(()),
136 Some(it) => it,
137 };
138 let target_module = match def_id.resolve(db)? {
139 Def::Module(it) => it,
140 _ => return Ok(()),
141 };
142 let module_scope = target_module.scope(db)?;
143 module_scope.entries().for_each(|(name, _res)| {
144 CompletionItem::new(name.to_string())
145 .kind(Reference)
146 .add_to(acc)
147 });
148 Ok(())
149}
150
151#[cfg(test)] 124#[cfg(test)]
152mod tests { 125mod tests {
153 use crate::completion::{CompletionKind, check_completion}; 126 use crate::completion::{CompletionKind, check_completion};