diff options
Diffstat (limited to 'crates/ra_analysis/src/completion/complete_scope.rs')
-rw-r--r-- | crates/ra_analysis/src/completion/complete_scope.rs | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/crates/ra_analysis/src/completion/complete_scope.rs b/crates/ra_analysis/src/completion/complete_scope.rs deleted file mode 100644 index ee9052d3d..000000000 --- a/crates/ra_analysis/src/completion/complete_scope.rs +++ /dev/null | |||
@@ -1,192 +0,0 @@ | |||
1 | use rustc_hash::FxHashSet; | ||
2 | use ra_syntax::TextUnit; | ||
3 | |||
4 | use crate::{ | ||
5 | Cancelable, | ||
6 | completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}, | ||
7 | }; | ||
8 | |||
9 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { | ||
10 | if !ctx.is_trivial_path { | ||
11 | return Ok(()); | ||
12 | } | ||
13 | let module = match &ctx.module { | ||
14 | Some(it) => it, | ||
15 | None => return Ok(()), | ||
16 | }; | ||
17 | if let Some(function) = &ctx.function { | ||
18 | let scopes = function.scopes(ctx.db)?; | ||
19 | complete_fn(acc, &scopes, ctx.offset); | ||
20 | } | ||
21 | |||
22 | let module_scope = module.scope(ctx.db)?; | ||
23 | let (file_id, _) = module.defenition_source(ctx.db)?; | ||
24 | module_scope | ||
25 | .entries() | ||
26 | .filter(|(_name, res)| { | ||
27 | // Don't expose this item | ||
28 | // FIXME: this penetrates through all kinds of abstractions, | ||
29 | // we need to figura out the way to do it less ugly. | ||
30 | match res.import { | ||
31 | None => true, | ||
32 | Some(import) => { | ||
33 | let range = import.range(ctx.db, file_id); | ||
34 | !range.is_subrange(&ctx.leaf.range()) | ||
35 | } | ||
36 | } | ||
37 | }) | ||
38 | .for_each(|(name, res)| { | ||
39 | CompletionItem::new(CompletionKind::Reference, name.to_string()) | ||
40 | .from_resolution(ctx, res) | ||
41 | .add_to(acc) | ||
42 | }); | ||
43 | Ok(()) | ||
44 | } | ||
45 | |||
46 | fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) { | ||
47 | let mut shadowed = FxHashSet::default(); | ||
48 | scopes | ||
49 | .scope_chain_for_offset(offset) | ||
50 | .flat_map(|scope| scopes.scopes.entries(scope).iter()) | ||
51 | .filter(|entry| shadowed.insert(entry.name())) | ||
52 | .for_each(|entry| { | ||
53 | CompletionItem::new(CompletionKind::Reference, entry.name().to_string()) | ||
54 | .kind(CompletionItemKind::Binding) | ||
55 | .add_to(acc) | ||
56 | }); | ||
57 | } | ||
58 | |||
59 | #[cfg(test)] | ||
60 | mod tests { | ||
61 | use crate::completion::{CompletionKind, check_completion}; | ||
62 | |||
63 | fn check_reference_completion(code: &str, expected_completions: &str) { | ||
64 | check_completion(code, expected_completions, CompletionKind::Reference); | ||
65 | } | ||
66 | |||
67 | #[test] | ||
68 | fn completes_bindings_from_let() { | ||
69 | check_reference_completion( | ||
70 | r" | ||
71 | fn quux(x: i32) { | ||
72 | let y = 92; | ||
73 | 1 + <|>; | ||
74 | let z = (); | ||
75 | } | ||
76 | ", | ||
77 | r#"y;x;quux "quux($0)""#, | ||
78 | ); | ||
79 | } | ||
80 | |||
81 | #[test] | ||
82 | fn completes_bindings_from_if_let() { | ||
83 | check_reference_completion( | ||
84 | r" | ||
85 | fn quux() { | ||
86 | if let Some(x) = foo() { | ||
87 | let y = 92; | ||
88 | }; | ||
89 | if let Some(a) = bar() { | ||
90 | let b = 62; | ||
91 | 1 + <|> | ||
92 | } | ||
93 | } | ||
94 | ", | ||
95 | r#"b;a;quux "quux()$0""#, | ||
96 | ); | ||
97 | } | ||
98 | |||
99 | #[test] | ||
100 | fn completes_bindings_from_for() { | ||
101 | check_reference_completion( | ||
102 | r" | ||
103 | fn quux() { | ||
104 | for x in &[1, 2, 3] { | ||
105 | <|> | ||
106 | } | ||
107 | } | ||
108 | ", | ||
109 | r#"x;quux "quux()$0""#, | ||
110 | ); | ||
111 | } | ||
112 | |||
113 | #[test] | ||
114 | fn completes_module_items() { | ||
115 | check_reference_completion( | ||
116 | r" | ||
117 | struct Foo; | ||
118 | enum Baz {} | ||
119 | fn quux() { | ||
120 | <|> | ||
121 | } | ||
122 | ", | ||
123 | r#"quux "quux()$0";Foo;Baz"#, | ||
124 | ); | ||
125 | } | ||
126 | |||
127 | #[test] | ||
128 | fn completes_module_items_in_nested_modules() { | ||
129 | check_reference_completion( | ||
130 | r" | ||
131 | struct Foo; | ||
132 | mod m { | ||
133 | struct Bar; | ||
134 | fn quux() { <|> } | ||
135 | } | ||
136 | ", | ||
137 | r#"quux "quux()$0";Bar"#, | ||
138 | ); | ||
139 | } | ||
140 | |||
141 | #[test] | ||
142 | fn completes_return_type() { | ||
143 | check_reference_completion( | ||
144 | r" | ||
145 | struct Foo; | ||
146 | fn x() -> <|> | ||
147 | ", | ||
148 | r#"Foo;x "x()$0""#, | ||
149 | ) | ||
150 | } | ||
151 | |||
152 | #[test] | ||
153 | fn dont_show_both_completions_for_shadowing() { | ||
154 | check_reference_completion( | ||
155 | r" | ||
156 | fn foo() -> { | ||
157 | let bar = 92; | ||
158 | { | ||
159 | let bar = 62; | ||
160 | <|> | ||
161 | } | ||
162 | } | ||
163 | ", | ||
164 | r#"bar;foo "foo()$0""#, | ||
165 | ) | ||
166 | } | ||
167 | |||
168 | #[test] | ||
169 | fn completes_self_in_methods() { | ||
170 | check_reference_completion(r"impl S { fn foo(&self) { <|> } }", "self") | ||
171 | } | ||
172 | |||
173 | #[test] | ||
174 | fn inserts_parens_for_function_calls() { | ||
175 | check_reference_completion( | ||
176 | r" | ||
177 | fn no_args() {} | ||
178 | fn main() { no_<|> } | ||
179 | ", | ||
180 | r#"no_args "no_args()$0" | ||
181 | main "main()$0""#, | ||
182 | ); | ||
183 | check_reference_completion( | ||
184 | r" | ||
185 | fn with_args(x: i32, y: String) {} | ||
186 | fn main() { with_<|> } | ||
187 | ", | ||
188 | r#"main "main()$0" | ||
189 | with_args "with_args($0)""#, | ||
190 | ); | ||
191 | } | ||
192 | } | ||