diff options
Diffstat (limited to 'crates/ide_db/src/call_info.rs')
-rw-r--r-- | crates/ide_db/src/call_info.rs | 527 |
1 files changed, 1 insertions, 526 deletions
diff --git a/crates/ide_db/src/call_info.rs b/crates/ide_db/src/call_info.rs index 83a602b9a..615fa7b0e 100644 --- a/crates/ide_db/src/call_info.rs +++ b/crates/ide_db/src/call_info.rs | |||
@@ -228,529 +228,4 @@ impl FnCallNode { | |||
228 | } | 228 | } |
229 | 229 | ||
230 | #[cfg(test)] | 230 | #[cfg(test)] |
231 | mod tests { | 231 | mod tests; |
232 | use crate::RootDatabase; | ||
233 | use base_db::{fixture::ChangeFixture, FilePosition}; | ||
234 | use expect_test::{expect, Expect}; | ||
235 | use test_utils::{mark, RangeOrOffset}; | ||
236 | |||
237 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | ||
238 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { | ||
239 | let change_fixture = ChangeFixture::parse(ra_fixture); | ||
240 | let mut database = RootDatabase::default(); | ||
241 | database.apply_change(change_fixture.change); | ||
242 | let (file_id, range_or_offset) = | ||
243 | change_fixture.file_position.expect("expected a marker (<|>)"); | ||
244 | let offset = match range_or_offset { | ||
245 | RangeOrOffset::Range(_) => panic!(), | ||
246 | RangeOrOffset::Offset(it) => it, | ||
247 | }; | ||
248 | (database, FilePosition { file_id, offset }) | ||
249 | } | ||
250 | |||
251 | fn check(ra_fixture: &str, expect: Expect) { | ||
252 | let (db, position) = position(ra_fixture); | ||
253 | let call_info = crate::call_info::call_info(&db, position); | ||
254 | let actual = match call_info { | ||
255 | Some(call_info) => { | ||
256 | let docs = match &call_info.doc { | ||
257 | None => "".to_string(), | ||
258 | Some(docs) => format!("{}\n------\n", docs.as_str()), | ||
259 | }; | ||
260 | let params = call_info | ||
261 | .parameter_labels() | ||
262 | .enumerate() | ||
263 | .map(|(i, param)| { | ||
264 | if Some(i) == call_info.active_parameter { | ||
265 | format!("<{}>", param) | ||
266 | } else { | ||
267 | param.to_string() | ||
268 | } | ||
269 | }) | ||
270 | .collect::<Vec<_>>() | ||
271 | .join(", "); | ||
272 | format!("{}{}\n({})\n", docs, call_info.signature, params) | ||
273 | } | ||
274 | None => String::new(), | ||
275 | }; | ||
276 | expect.assert_eq(&actual); | ||
277 | } | ||
278 | |||
279 | #[test] | ||
280 | fn test_fn_signature_two_args() { | ||
281 | check( | ||
282 | r#" | ||
283 | fn foo(x: u32, y: u32) -> u32 {x + y} | ||
284 | fn bar() { foo(<|>3, ); } | ||
285 | "#, | ||
286 | expect![[r#" | ||
287 | fn foo(x: u32, y: u32) -> u32 | ||
288 | (<x: u32>, y: u32) | ||
289 | "#]], | ||
290 | ); | ||
291 | check( | ||
292 | r#" | ||
293 | fn foo(x: u32, y: u32) -> u32 {x + y} | ||
294 | fn bar() { foo(3<|>, ); } | ||
295 | "#, | ||
296 | expect![[r#" | ||
297 | fn foo(x: u32, y: u32) -> u32 | ||
298 | (<x: u32>, y: u32) | ||
299 | "#]], | ||
300 | ); | ||
301 | check( | ||
302 | r#" | ||
303 | fn foo(x: u32, y: u32) -> u32 {x + y} | ||
304 | fn bar() { foo(3,<|> ); } | ||
305 | "#, | ||
306 | expect![[r#" | ||
307 | fn foo(x: u32, y: u32) -> u32 | ||
308 | (x: u32, <y: u32>) | ||
309 | "#]], | ||
310 | ); | ||
311 | check( | ||
312 | r#" | ||
313 | fn foo(x: u32, y: u32) -> u32 {x + y} | ||
314 | fn bar() { foo(3, <|>); } | ||
315 | "#, | ||
316 | expect![[r#" | ||
317 | fn foo(x: u32, y: u32) -> u32 | ||
318 | (x: u32, <y: u32>) | ||
319 | "#]], | ||
320 | ); | ||
321 | } | ||
322 | |||
323 | #[test] | ||
324 | fn test_fn_signature_two_args_empty() { | ||
325 | check( | ||
326 | r#" | ||
327 | fn foo(x: u32, y: u32) -> u32 {x + y} | ||
328 | fn bar() { foo(<|>); } | ||
329 | "#, | ||
330 | expect![[r#" | ||
331 | fn foo(x: u32, y: u32) -> u32 | ||
332 | (<x: u32>, y: u32) | ||
333 | "#]], | ||
334 | ); | ||
335 | } | ||
336 | |||
337 | #[test] | ||
338 | fn test_fn_signature_two_args_first_generics() { | ||
339 | check( | ||
340 | r#" | ||
341 | fn foo<T, U: Copy + Display>(x: T, y: U) -> u32 | ||
342 | where T: Copy + Display, U: Debug | ||
343 | { x + y } | ||
344 | |||
345 | fn bar() { foo(<|>3, ); } | ||
346 | "#, | ||
347 | expect![[r#" | ||
348 | fn foo(x: i32, y: {unknown}) -> u32 | ||
349 | (<x: i32>, y: {unknown}) | ||
350 | "#]], | ||
351 | ); | ||
352 | } | ||
353 | |||
354 | #[test] | ||
355 | fn test_fn_signature_no_params() { | ||
356 | check( | ||
357 | r#" | ||
358 | fn foo<T>() -> T where T: Copy + Display {} | ||
359 | fn bar() { foo(<|>); } | ||
360 | "#, | ||
361 | expect![[r#" | ||
362 | fn foo() -> {unknown} | ||
363 | () | ||
364 | "#]], | ||
365 | ); | ||
366 | } | ||
367 | |||
368 | #[test] | ||
369 | fn test_fn_signature_for_impl() { | ||
370 | check( | ||
371 | r#" | ||
372 | struct F; | ||
373 | impl F { pub fn new() { } } | ||
374 | fn bar() { | ||
375 | let _ : F = F::new(<|>); | ||
376 | } | ||
377 | "#, | ||
378 | expect![[r#" | ||
379 | fn new() | ||
380 | () | ||
381 | "#]], | ||
382 | ); | ||
383 | } | ||
384 | |||
385 | #[test] | ||
386 | fn test_fn_signature_for_method_self() { | ||
387 | check( | ||
388 | r#" | ||
389 | struct S; | ||
390 | impl S { pub fn do_it(&self) {} } | ||
391 | |||
392 | fn bar() { | ||
393 | let s: S = S; | ||
394 | s.do_it(<|>); | ||
395 | } | ||
396 | "#, | ||
397 | expect![[r#" | ||
398 | fn do_it(&self) | ||
399 | () | ||
400 | "#]], | ||
401 | ); | ||
402 | } | ||
403 | |||
404 | #[test] | ||
405 | fn test_fn_signature_for_method_with_arg() { | ||
406 | check( | ||
407 | r#" | ||
408 | struct S; | ||
409 | impl S { | ||
410 | fn foo(&self, x: i32) {} | ||
411 | } | ||
412 | |||
413 | fn main() { S.foo(<|>); } | ||
414 | "#, | ||
415 | expect![[r#" | ||
416 | fn foo(&self, x: i32) | ||
417 | (<x: i32>) | ||
418 | "#]], | ||
419 | ); | ||
420 | } | ||
421 | |||
422 | #[test] | ||
423 | fn test_fn_signature_for_method_with_arg_as_assoc_fn() { | ||
424 | check( | ||
425 | r#" | ||
426 | struct S; | ||
427 | impl S { | ||
428 | fn foo(&self, x: i32) {} | ||
429 | } | ||
430 | |||
431 | fn main() { S::foo(<|>); } | ||
432 | "#, | ||
433 | expect![[r#" | ||
434 | fn foo(self: &S, x: i32) | ||
435 | (<self: &S>, x: i32) | ||
436 | "#]], | ||
437 | ); | ||
438 | } | ||
439 | |||
440 | #[test] | ||
441 | fn test_fn_signature_with_docs_simple() { | ||
442 | check( | ||
443 | r#" | ||
444 | /// test | ||
445 | // non-doc-comment | ||
446 | fn foo(j: u32) -> u32 { | ||
447 | j | ||
448 | } | ||
449 | |||
450 | fn bar() { | ||
451 | let _ = foo(<|>); | ||
452 | } | ||
453 | "#, | ||
454 | expect![[r#" | ||
455 | test | ||
456 | ------ | ||
457 | fn foo(j: u32) -> u32 | ||
458 | (<j: u32>) | ||
459 | "#]], | ||
460 | ); | ||
461 | } | ||
462 | |||
463 | #[test] | ||
464 | fn test_fn_signature_with_docs() { | ||
465 | check( | ||
466 | r#" | ||
467 | /// Adds one to the number given. | ||
468 | /// | ||
469 | /// # Examples | ||
470 | /// | ||
471 | /// ``` | ||
472 | /// let five = 5; | ||
473 | /// | ||
474 | /// assert_eq!(6, my_crate::add_one(5)); | ||
475 | /// ``` | ||
476 | pub fn add_one(x: i32) -> i32 { | ||
477 | x + 1 | ||
478 | } | ||
479 | |||
480 | pub fn do() { | ||
481 | add_one(<|> | ||
482 | }"#, | ||
483 | expect![[r##" | ||
484 | Adds one to the number given. | ||
485 | |||
486 | # Examples | ||
487 | |||
488 | ``` | ||
489 | let five = 5; | ||
490 | |||
491 | assert_eq!(6, my_crate::add_one(5)); | ||
492 | ``` | ||
493 | ------ | ||
494 | fn add_one(x: i32) -> i32 | ||
495 | (<x: i32>) | ||
496 | "##]], | ||
497 | ); | ||
498 | } | ||
499 | |||
500 | #[test] | ||
501 | fn test_fn_signature_with_docs_impl() { | ||
502 | check( | ||
503 | r#" | ||
504 | struct addr; | ||
505 | impl addr { | ||
506 | /// Adds one to the number given. | ||
507 | /// | ||
508 | /// # Examples | ||
509 | /// | ||
510 | /// ``` | ||
511 | /// let five = 5; | ||
512 | /// | ||
513 | /// assert_eq!(6, my_crate::add_one(5)); | ||
514 | /// ``` | ||
515 | pub fn add_one(x: i32) -> i32 { | ||
516 | x + 1 | ||
517 | } | ||
518 | } | ||
519 | |||
520 | pub fn do_it() { | ||
521 | addr {}; | ||
522 | addr::add_one(<|>); | ||
523 | } | ||
524 | "#, | ||
525 | expect![[r##" | ||
526 | Adds one to the number given. | ||
527 | |||
528 | # Examples | ||
529 | |||
530 | ``` | ||
531 | let five = 5; | ||
532 | |||
533 | assert_eq!(6, my_crate::add_one(5)); | ||
534 | ``` | ||
535 | ------ | ||
536 | fn add_one(x: i32) -> i32 | ||
537 | (<x: i32>) | ||
538 | "##]], | ||
539 | ); | ||
540 | } | ||
541 | |||
542 | #[test] | ||
543 | fn test_fn_signature_with_docs_from_actix() { | ||
544 | check( | ||
545 | r#" | ||
546 | struct WriteHandler<E>; | ||
547 | |||
548 | impl<E> WriteHandler<E> { | ||
549 | /// Method is called when writer emits error. | ||
550 | /// | ||
551 | /// If this method returns `ErrorAction::Continue` writer processing | ||
552 | /// continues otherwise stream processing stops. | ||
553 | fn error(&mut self, err: E, ctx: &mut Self::Context) -> Running { | ||
554 | Running::Stop | ||
555 | } | ||
556 | |||
557 | /// Method is called when writer finishes. | ||
558 | /// | ||
559 | /// By default this method stops actor's `Context`. | ||
560 | fn finished(&mut self, ctx: &mut Self::Context) { | ||
561 | ctx.stop() | ||
562 | } | ||
563 | } | ||
564 | |||
565 | pub fn foo(mut r: WriteHandler<()>) { | ||
566 | r.finished(<|>); | ||
567 | } | ||
568 | "#, | ||
569 | expect![[r#" | ||
570 | Method is called when writer finishes. | ||
571 | |||
572 | By default this method stops actor's `Context`. | ||
573 | ------ | ||
574 | fn finished(&mut self, ctx: &mut {unknown}) | ||
575 | (<ctx: &mut {unknown}>) | ||
576 | "#]], | ||
577 | ); | ||
578 | } | ||
579 | |||
580 | #[test] | ||
581 | fn call_info_bad_offset() { | ||
582 | mark::check!(call_info_bad_offset); | ||
583 | check( | ||
584 | r#" | ||
585 | fn foo(x: u32, y: u32) -> u32 {x + y} | ||
586 | fn bar() { foo <|> (3, ); } | ||
587 | "#, | ||
588 | expect![[""]], | ||
589 | ); | ||
590 | } | ||
591 | |||
592 | #[test] | ||
593 | fn test_nested_method_in_lambda() { | ||
594 | check( | ||
595 | r#" | ||
596 | struct Foo; | ||
597 | impl Foo { fn bar(&self, _: u32) { } } | ||
598 | |||
599 | fn bar(_: u32) { } | ||
600 | |||
601 | fn main() { | ||
602 | let foo = Foo; | ||
603 | std::thread::spawn(move || foo.bar(<|>)); | ||
604 | } | ||
605 | "#, | ||
606 | expect![[r#" | ||
607 | fn bar(&self, _: u32) | ||
608 | (<_: u32>) | ||
609 | "#]], | ||
610 | ); | ||
611 | } | ||
612 | |||
613 | #[test] | ||
614 | fn works_for_tuple_structs() { | ||
615 | check( | ||
616 | r#" | ||
617 | /// A cool tuple struct | ||
618 | struct S(u32, i32); | ||
619 | fn main() { | ||
620 | let s = S(0, <|>); | ||
621 | } | ||
622 | "#, | ||
623 | expect![[r#" | ||
624 | A cool tuple struct | ||
625 | ------ | ||
626 | struct S(u32, i32) | ||
627 | (u32, <i32>) | ||
628 | "#]], | ||
629 | ); | ||
630 | } | ||
631 | |||
632 | #[test] | ||
633 | fn generic_struct() { | ||
634 | check( | ||
635 | r#" | ||
636 | struct S<T>(T); | ||
637 | fn main() { | ||
638 | let s = S(<|>); | ||
639 | } | ||
640 | "#, | ||
641 | expect![[r#" | ||
642 | struct S({unknown}) | ||
643 | (<{unknown}>) | ||
644 | "#]], | ||
645 | ); | ||
646 | } | ||
647 | |||
648 | #[test] | ||
649 | fn works_for_enum_variants() { | ||
650 | check( | ||
651 | r#" | ||
652 | enum E { | ||
653 | /// A Variant | ||
654 | A(i32), | ||
655 | /// Another | ||
656 | B, | ||
657 | /// And C | ||
658 | C { a: i32, b: i32 } | ||
659 | } | ||
660 | |||
661 | fn main() { | ||
662 | let a = E::A(<|>); | ||
663 | } | ||
664 | "#, | ||
665 | expect![[r#" | ||
666 | A Variant | ||
667 | ------ | ||
668 | enum E::A(i32) | ||
669 | (<i32>) | ||
670 | "#]], | ||
671 | ); | ||
672 | } | ||
673 | |||
674 | #[test] | ||
675 | fn cant_call_struct_record() { | ||
676 | check( | ||
677 | r#" | ||
678 | struct S { x: u32, y: i32 } | ||
679 | fn main() { | ||
680 | let s = S(<|>); | ||
681 | } | ||
682 | "#, | ||
683 | expect![[""]], | ||
684 | ); | ||
685 | } | ||
686 | |||
687 | #[test] | ||
688 | fn cant_call_enum_record() { | ||
689 | check( | ||
690 | r#" | ||
691 | enum E { | ||
692 | /// A Variant | ||
693 | A(i32), | ||
694 | /// Another | ||
695 | B, | ||
696 | /// And C | ||
697 | C { a: i32, b: i32 } | ||
698 | } | ||
699 | |||
700 | fn main() { | ||
701 | let a = E::C(<|>); | ||
702 | } | ||
703 | "#, | ||
704 | expect![[""]], | ||
705 | ); | ||
706 | } | ||
707 | |||
708 | #[test] | ||
709 | fn fn_signature_for_call_in_macro() { | ||
710 | check( | ||
711 | r#" | ||
712 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } | ||
713 | fn foo() { } | ||
714 | id! { | ||
715 | fn bar() { foo(<|>); } | ||
716 | } | ||
717 | "#, | ||
718 | expect![[r#" | ||
719 | fn foo() | ||
720 | () | ||
721 | "#]], | ||
722 | ); | ||
723 | } | ||
724 | |||
725 | #[test] | ||
726 | fn call_info_for_lambdas() { | ||
727 | check( | ||
728 | r#" | ||
729 | struct S; | ||
730 | fn foo(s: S) -> i32 { 92 } | ||
731 | fn main() { | ||
732 | (|s| foo(s))(<|>) | ||
733 | } | ||
734 | "#, | ||
735 | expect![[r#" | ||
736 | (S) -> i32 | ||
737 | (<S>) | ||
738 | "#]], | ||
739 | ) | ||
740 | } | ||
741 | |||
742 | #[test] | ||
743 | fn call_info_for_fn_ptr() { | ||
744 | check( | ||
745 | r#" | ||
746 | fn main(f: fn(i32, f64) -> char) { | ||
747 | f(0, <|>) | ||
748 | } | ||
749 | "#, | ||
750 | expect![[r#" | ||
751 | (i32, f64) -> char | ||
752 | (i32, <f64>) | ||
753 | "#]], | ||
754 | ) | ||
755 | } | ||
756 | } | ||