diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_scope.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_scope.rs | 447 |
1 files changed, 344 insertions, 103 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index f92034055..2000d953a 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -121,172 +121,413 @@ impl ImportResolver { | |||
121 | 121 | ||
122 | #[cfg(test)] | 122 | #[cfg(test)] |
123 | mod tests { | 123 | mod tests { |
124 | use crate::completion::{check_completion, CompletionKind}; | 124 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; |
125 | use insta::assert_debug_snapshot_matches; | ||
125 | 126 | ||
126 | fn check_reference_completion(name: &str, code: &str) { | 127 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { |
127 | check_completion(name, code, CompletionKind::Reference); | 128 | do_completion(code, CompletionKind::Reference) |
128 | } | 129 | } |
129 | 130 | ||
130 | #[test] | 131 | #[test] |
131 | fn completes_bindings_from_let() { | 132 | fn completes_bindings_from_let() { |
132 | check_reference_completion( | 133 | assert_debug_snapshot_matches!( |
133 | "bindings_from_let", | 134 | do_reference_completion( |
134 | r" | 135 | r" |
135 | fn quux(x: i32) { | 136 | fn quux(x: i32) { |
136 | let y = 92; | 137 | let y = 92; |
137 | 1 + <|>; | 138 | 1 + <|>; |
138 | let z = (); | 139 | let z = (); |
139 | } | 140 | } |
140 | ", | 141 | " |
142 | ), | ||
143 | @r###"[ | ||
144 | CompletionItem { | ||
145 | label: "quux", | ||
146 | source_range: [91; 91), | ||
147 | delete: [91; 91), | ||
148 | insert: "quux($0)", | ||
149 | kind: Function, | ||
150 | detail: "fn quux(x: i32)", | ||
151 | }, | ||
152 | CompletionItem { | ||
153 | label: "x", | ||
154 | source_range: [91; 91), | ||
155 | delete: [91; 91), | ||
156 | insert: "x", | ||
157 | kind: Binding, | ||
158 | detail: "i32", | ||
159 | }, | ||
160 | CompletionItem { | ||
161 | label: "y", | ||
162 | source_range: [91; 91), | ||
163 | delete: [91; 91), | ||
164 | insert: "y", | ||
165 | kind: Binding, | ||
166 | detail: "i32", | ||
167 | }, | ||
168 | ]"### | ||
141 | ); | 169 | ); |
142 | } | 170 | } |
143 | 171 | ||
144 | #[test] | 172 | #[test] |
145 | fn completes_bindings_from_if_let() { | 173 | fn completes_bindings_from_if_let() { |
146 | check_reference_completion( | 174 | assert_debug_snapshot_matches!( |
147 | "bindings_from_if_let", | 175 | do_reference_completion( |
148 | r" | 176 | r" |
149 | fn quux() { | 177 | fn quux() { |
150 | if let Some(x) = foo() { | 178 | if let Some(x) = foo() { |
151 | let y = 92; | 179 | let y = 92; |
152 | }; | 180 | }; |
153 | if let Some(a) = bar() { | 181 | if let Some(a) = bar() { |
154 | let b = 62; | 182 | let b = 62; |
155 | 1 + <|> | 183 | 1 + <|> |
184 | } | ||
156 | } | 185 | } |
157 | } | 186 | " |
158 | ", | 187 | ), |
188 | @r###"[ | ||
189 | CompletionItem { | ||
190 | label: "a", | ||
191 | source_range: [242; 242), | ||
192 | delete: [242; 242), | ||
193 | insert: "a", | ||
194 | kind: Binding, | ||
195 | }, | ||
196 | CompletionItem { | ||
197 | label: "b", | ||
198 | source_range: [242; 242), | ||
199 | delete: [242; 242), | ||
200 | insert: "b", | ||
201 | kind: Binding, | ||
202 | detail: "i32", | ||
203 | }, | ||
204 | CompletionItem { | ||
205 | label: "quux", | ||
206 | source_range: [242; 242), | ||
207 | delete: [242; 242), | ||
208 | insert: "quux()$0", | ||
209 | kind: Function, | ||
210 | detail: "fn quux()", | ||
211 | }, | ||
212 | ]"### | ||
159 | ); | 213 | ); |
160 | } | 214 | } |
161 | 215 | ||
162 | #[test] | 216 | #[test] |
163 | fn completes_bindings_from_for() { | 217 | fn completes_bindings_from_for() { |
164 | check_reference_completion( | 218 | assert_debug_snapshot_matches!( |
165 | "bindings_from_for", | 219 | do_reference_completion( |
166 | r" | 220 | r" |
167 | fn quux() { | 221 | fn quux() { |
168 | for x in &[1, 2, 3] { | 222 | for x in &[1, 2, 3] { |
169 | <|> | 223 | <|> |
224 | } | ||
170 | } | 225 | } |
171 | } | 226 | " |
172 | ", | 227 | ), |
228 | @r###"[ | ||
229 | CompletionItem { | ||
230 | label: "quux", | ||
231 | source_range: [95; 95), | ||
232 | delete: [95; 95), | ||
233 | insert: "quux()$0", | ||
234 | kind: Function, | ||
235 | detail: "fn quux()", | ||
236 | }, | ||
237 | CompletionItem { | ||
238 | label: "x", | ||
239 | source_range: [95; 95), | ||
240 | delete: [95; 95), | ||
241 | insert: "x", | ||
242 | kind: Binding, | ||
243 | }, | ||
244 | ]"### | ||
173 | ); | 245 | ); |
174 | } | 246 | } |
175 | 247 | ||
176 | #[test] | 248 | #[test] |
177 | fn completes_generic_params() { | 249 | fn completes_generic_params() { |
178 | check_reference_completion( | 250 | assert_debug_snapshot_matches!( |
179 | "generic_params", | 251 | do_reference_completion( |
180 | r" | 252 | r" |
181 | fn quux<T>() { | 253 | fn quux<T>() { |
182 | <|> | 254 | <|> |
183 | } | 255 | } |
184 | ", | 256 | " |
257 | ), | ||
258 | @r###"[ | ||
259 | CompletionItem { | ||
260 | label: "T", | ||
261 | source_range: [52; 52), | ||
262 | delete: [52; 52), | ||
263 | insert: "T", | ||
264 | kind: TypeParam, | ||
265 | }, | ||
266 | CompletionItem { | ||
267 | label: "quux", | ||
268 | source_range: [52; 52), | ||
269 | delete: [52; 52), | ||
270 | insert: "quux()$0", | ||
271 | kind: Function, | ||
272 | detail: "fn quux<T>()", | ||
273 | }, | ||
274 | ]"### | ||
185 | ); | 275 | ); |
186 | } | 276 | } |
187 | 277 | ||
188 | #[test] | 278 | #[test] |
189 | fn completes_generic_params_in_struct() { | 279 | fn completes_generic_params_in_struct() { |
190 | check_reference_completion( | 280 | assert_debug_snapshot_matches!( |
191 | "generic_params_in_struct", | 281 | do_reference_completion( |
192 | r" | 282 | r" |
193 | struct X<T> { | 283 | struct X<T> { |
194 | x: <|> | 284 | x: <|> |
195 | } | 285 | } |
196 | ", | 286 | " |
287 | ), | ||
288 | @r###"[ | ||
289 | CompletionItem { | ||
290 | label: "T", | ||
291 | source_range: [54; 54), | ||
292 | delete: [54; 54), | ||
293 | insert: "T", | ||
294 | kind: TypeParam, | ||
295 | }, | ||
296 | CompletionItem { | ||
297 | label: "X", | ||
298 | source_range: [54; 54), | ||
299 | delete: [54; 54), | ||
300 | insert: "X", | ||
301 | kind: Struct, | ||
302 | }, | ||
303 | ]"### | ||
197 | ); | 304 | ); |
198 | } | 305 | } |
199 | 306 | ||
200 | #[test] | 307 | #[test] |
201 | fn completes_module_items() { | 308 | fn completes_module_items() { |
202 | check_reference_completion( | 309 | assert_debug_snapshot_matches!( |
203 | "module_items", | 310 | do_reference_completion( |
204 | r" | 311 | r" |
205 | struct Foo; | 312 | struct Foo; |
206 | enum Baz {} | 313 | enum Baz {} |
207 | fn quux() { | 314 | fn quux() { |
208 | <|> | 315 | <|> |
209 | } | 316 | } |
210 | ", | 317 | " |
211 | ); | 318 | ), |
319 | @r###"[ | ||
320 | CompletionItem { | ||
321 | label: "Baz", | ||
322 | source_range: [105; 105), | ||
323 | delete: [105; 105), | ||
324 | insert: "Baz", | ||
325 | kind: Enum, | ||
326 | }, | ||
327 | CompletionItem { | ||
328 | label: "Foo", | ||
329 | source_range: [105; 105), | ||
330 | delete: [105; 105), | ||
331 | insert: "Foo", | ||
332 | kind: Struct, | ||
333 | }, | ||
334 | CompletionItem { | ||
335 | label: "quux", | ||
336 | source_range: [105; 105), | ||
337 | delete: [105; 105), | ||
338 | insert: "quux()$0", | ||
339 | kind: Function, | ||
340 | detail: "fn quux()", | ||
341 | }, | ||
342 | ]"### | ||
343 | ); | ||
212 | } | 344 | } |
213 | 345 | ||
214 | #[test] | 346 | #[test] |
215 | fn completes_extern_prelude() { | 347 | fn completes_extern_prelude() { |
216 | check_reference_completion( | 348 | assert_debug_snapshot_matches!( |
217 | "extern_prelude", | 349 | do_reference_completion( |
218 | r" | 350 | r" |
219 | //- /lib.rs | 351 | //- /lib.rs |
220 | use <|>; | 352 | use <|>; |
221 | 353 | ||
222 | //- /other_crate/lib.rs | 354 | //- /other_crate/lib.rs |
223 | // nothing here | 355 | // nothing here |
224 | ", | 356 | " |
357 | ), | ||
358 | @r#"[ | ||
359 | CompletionItem { | ||
360 | label: "other_crate", | ||
361 | source_range: [4; 4), | ||
362 | delete: [4; 4), | ||
363 | insert: "other_crate", | ||
364 | kind: Module, | ||
365 | }, | ||
366 | ]"# | ||
225 | ); | 367 | ); |
226 | } | 368 | } |
227 | 369 | ||
228 | #[test] | 370 | #[test] |
229 | fn completes_module_items_in_nested_modules() { | 371 | fn completes_module_items_in_nested_modules() { |
230 | check_reference_completion( | 372 | assert_debug_snapshot_matches!( |
231 | "module_items_in_nested_modules", | 373 | do_reference_completion( |
232 | r" | 374 | r" |
233 | struct Foo; | 375 | struct Foo; |
234 | mod m { | 376 | mod m { |
235 | struct Bar; | 377 | struct Bar; |
236 | fn quux() { <|> } | 378 | fn quux() { <|> } |
237 | } | 379 | } |
238 | ", | 380 | " |
381 | ), | ||
382 | @r###"[ | ||
383 | CompletionItem { | ||
384 | label: "Bar", | ||
385 | source_range: [117; 117), | ||
386 | delete: [117; 117), | ||
387 | insert: "Bar", | ||
388 | kind: Struct, | ||
389 | }, | ||
390 | CompletionItem { | ||
391 | label: "quux", | ||
392 | source_range: [117; 117), | ||
393 | delete: [117; 117), | ||
394 | insert: "quux()$0", | ||
395 | kind: Function, | ||
396 | detail: "fn quux()", | ||
397 | }, | ||
398 | ]"### | ||
239 | ); | 399 | ); |
240 | } | 400 | } |
241 | 401 | ||
242 | #[test] | 402 | #[test] |
243 | fn completes_return_type() { | 403 | fn completes_return_type() { |
244 | check_reference_completion( | 404 | assert_debug_snapshot_matches!( |
245 | "return_type", | 405 | do_reference_completion( |
246 | r" | 406 | r" |
247 | struct Foo; | 407 | struct Foo; |
248 | fn x() -> <|> | 408 | fn x() -> <|> |
249 | ", | 409 | " |
250 | ) | 410 | ), |
411 | @r###"[ | ||
412 | CompletionItem { | ||
413 | label: "Foo", | ||
414 | source_range: [55; 55), | ||
415 | delete: [55; 55), | ||
416 | insert: "Foo", | ||
417 | kind: Struct, | ||
418 | }, | ||
419 | CompletionItem { | ||
420 | label: "x", | ||
421 | source_range: [55; 55), | ||
422 | delete: [55; 55), | ||
423 | insert: "x()$0", | ||
424 | kind: Function, | ||
425 | detail: "fn x()", | ||
426 | }, | ||
427 | ]"### | ||
428 | ); | ||
251 | } | 429 | } |
252 | 430 | ||
253 | #[test] | 431 | #[test] |
254 | fn dont_show_both_completions_for_shadowing() { | 432 | fn dont_show_both_completions_for_shadowing() { |
255 | check_reference_completion( | 433 | assert_debug_snapshot_matches!( |
256 | "dont_show_both_completions_for_shadowing", | 434 | do_reference_completion( |
257 | r" | 435 | r" |
258 | fn foo() { | 436 | fn foo() { |
259 | let bar = 92; | 437 | let bar = 92; |
260 | { | 438 | { |
261 | let bar = 62; | 439 | let bar = 62; |
262 | <|> | 440 | <|> |
441 | } | ||
263 | } | 442 | } |
264 | } | 443 | " |
265 | ", | 444 | ), |
266 | ) | 445 | @r###"[ |
446 | CompletionItem { | ||
447 | label: "bar", | ||
448 | source_range: [146; 146), | ||
449 | delete: [146; 146), | ||
450 | insert: "bar", | ||
451 | kind: Binding, | ||
452 | detail: "i32", | ||
453 | }, | ||
454 | CompletionItem { | ||
455 | label: "foo", | ||
456 | source_range: [146; 146), | ||
457 | delete: [146; 146), | ||
458 | insert: "foo()$0", | ||
459 | kind: Function, | ||
460 | detail: "fn foo()", | ||
461 | }, | ||
462 | ]"### | ||
463 | ); | ||
267 | } | 464 | } |
268 | 465 | ||
269 | #[test] | 466 | #[test] |
270 | fn completes_self_in_methods() { | 467 | fn completes_self_in_methods() { |
271 | check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") | 468 | assert_debug_snapshot_matches!( |
469 | do_reference_completion(r"impl S { fn foo(&self) { <|> } }"), | ||
470 | @r#"[ | ||
471 | CompletionItem { | ||
472 | label: "Self", | ||
473 | source_range: [25; 25), | ||
474 | delete: [25; 25), | ||
475 | insert: "Self", | ||
476 | kind: TypeParam, | ||
477 | }, | ||
478 | CompletionItem { | ||
479 | label: "self", | ||
480 | source_range: [25; 25), | ||
481 | delete: [25; 25), | ||
482 | insert: "self", | ||
483 | kind: Binding, | ||
484 | detail: "&{unknown}", | ||
485 | }, | ||
486 | ]"# | ||
487 | ); | ||
272 | } | 488 | } |
273 | 489 | ||
274 | #[test] | 490 | #[test] |
275 | fn completes_prelude() { | 491 | fn completes_prelude() { |
276 | check_reference_completion( | 492 | assert_debug_snapshot_matches!( |
277 | "completes_prelude", | 493 | do_reference_completion( |
278 | " | 494 | " |
279 | //- /main.rs | 495 | //- /main.rs |
280 | fn foo() { let x: <|> } | 496 | fn foo() { let x: <|> } |
281 | 497 | ||
282 | //- /std/lib.rs | 498 | //- /std/lib.rs |
283 | #[prelude_import] | 499 | #[prelude_import] |
284 | use prelude::*; | 500 | use prelude::*; |
285 | 501 | ||
286 | mod prelude { | 502 | mod prelude { |
287 | struct Option; | 503 | struct Option; |
288 | } | 504 | } |
289 | ", | 505 | " |
506 | ), | ||
507 | @r#"[ | ||
508 | CompletionItem { | ||
509 | label: "Option", | ||
510 | source_range: [18; 18), | ||
511 | delete: [18; 18), | ||
512 | insert: "Option", | ||
513 | kind: Struct, | ||
514 | }, | ||
515 | CompletionItem { | ||
516 | label: "foo", | ||
517 | source_range: [18; 18), | ||
518 | delete: [18; 18), | ||
519 | insert: "foo()$0", | ||
520 | kind: Function, | ||
521 | detail: "fn foo()", | ||
522 | }, | ||
523 | CompletionItem { | ||
524 | label: "std", | ||
525 | source_range: [18; 18), | ||
526 | delete: [18; 18), | ||
527 | insert: "std", | ||
528 | kind: Module, | ||
529 | }, | ||
530 | ]"# | ||
290 | ); | 531 | ); |
291 | } | 532 | } |
292 | } | 533 | } |