aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src/call_info.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src/call_info.rs')
-rw-r--r--crates/ide_db/src/call_info.rs527
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)]
231mod tests { 231mod 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#"
283fn foo(x: u32, y: u32) -> u32 {x + y}
284fn 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#"
293fn foo(x: u32, y: u32) -> u32 {x + y}
294fn 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#"
303fn foo(x: u32, y: u32) -> u32 {x + y}
304fn 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#"
313fn foo(x: u32, y: u32) -> u32 {x + y}
314fn 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#"
327fn foo(x: u32, y: u32) -> u32 {x + y}
328fn 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#"
341fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
342 where T: Copy + Display, U: Debug
343{ x + y }
344
345fn 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#"
358fn foo<T>() -> T where T: Copy + Display {}
359fn 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#"
372struct F;
373impl F { pub fn new() { } }
374fn 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#"
389struct S;
390impl S { pub fn do_it(&self) {} }
391
392fn 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#"
408struct S;
409impl S {
410 fn foo(&self, x: i32) {}
411}
412
413fn 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#"
426struct S;
427impl S {
428 fn foo(&self, x: i32) {}
429}
430
431fn 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
446fn foo(j: u32) -> u32 {
447 j
448}
449
450fn 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/// ```
476pub fn add_one(x: i32) -> i32 {
477 x + 1
478}
479
480pub 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#"
504struct addr;
505impl 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
520pub 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#"
546struct WriteHandler<E>;
547
548impl<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
565pub 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#"
585fn foo(x: u32, y: u32) -> u32 {x + y}
586fn bar() { foo <|> (3, ); }
587"#,
588 expect![[""]],
589 );
590 }
591
592 #[test]
593 fn test_nested_method_in_lambda() {
594 check(
595 r#"
596struct Foo;
597impl Foo { fn bar(&self, _: u32) { } }
598
599fn bar(_: u32) { }
600
601fn 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
618struct S(u32, i32);
619fn 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#"
636struct S<T>(T);
637fn 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#"
652enum E {
653 /// A Variant
654 A(i32),
655 /// Another
656 B,
657 /// And C
658 C { a: i32, b: i32 }
659}
660
661fn 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#"
678struct S { x: u32, y: i32 }
679fn main() {
680 let s = S(<|>);
681}
682"#,
683 expect![[""]],
684 );
685 }
686
687 #[test]
688 fn cant_call_enum_record() {
689 check(
690 r#"
691enum E {
692 /// A Variant
693 A(i32),
694 /// Another
695 B,
696 /// And C
697 C { a: i32, b: i32 }
698}
699
700fn 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#"
712macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
713fn foo() { }
714id! {
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#"
729struct S;
730fn foo(s: S) -> i32 { 92 }
731fn 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#"
746fn 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}