Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / language-server / src / tests / reference.rs
29 kB 1725 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2025 The Gleam contributors 3 4use std::collections::HashMap; 5 6use lsp_types::{ 7 PartialResultParams, Position, Range, ReferenceContext, ReferenceParams, 8 TextDocumentPositionParams, WorkDoneProgressParams, 9}; 10 11use super::{TestProject, find_position_of}; 12 13fn find_references( 14 tester: &TestProject<'_>, 15 position: Position, 16) -> Option<HashMap<String, Vec<Range>>> { 17 let locations = tester.at(position, |engine, params, _| { 18 let params = ReferenceParams { 19 text_document_position_params: TextDocumentPositionParams { 20 text_document: params.text_document, 21 position, 22 }, 23 work_done_progress_params: WorkDoneProgressParams::default(), 24 partial_result_params: PartialResultParams::default(), 25 context: ReferenceContext { 26 include_declaration: true, 27 }, 28 }; 29 engine.find_references(params).result.unwrap() 30 })?; 31 let mut references: HashMap<String, Vec<Range>> = HashMap::new(); 32 33 for location in locations { 34 let module_name = tester 35 .module_name_from_url(&location.uri) 36 .expect("Valid uri"); 37 _ = references 38 .entry(module_name) 39 .or_default() 40 .push(location.range); 41 } 42 43 Some(references) 44} 45 46fn show_references(code: &str, position: Option<Position>, ranges: &[Range]) -> String { 47 let mut buffer = String::new(); 48 49 for (line_number, line) in code.lines().enumerate() { 50 let mut underline = String::new(); 51 let mut underline_empty = true; 52 let line_number = line_number as u32; 53 54 for (column_number, _) in line.chars().enumerate() { 55 let current_position = Position::new(line_number, column_number as u32); 56 57 // Check if any range covers this specific character 58 let is_in_range = ranges 59 .iter() 60 .any(|range| range.start <= current_position && current_position < range.end); 61 62 if Some(current_position) == position { 63 underline_empty = false; 64 underline.push('↑'); 65 } else if is_in_range { 66 underline_empty = false; 67 underline.push('▔'); 68 } else { 69 underline.push(' '); 70 } 71 } 72 73 buffer.push_str(line); 74 if !underline_empty { 75 buffer.push('\n'); 76 buffer.push_str(&underline); 77 } 78 buffer.push('\n'); 79 } 80 81 buffer 82} 83 84macro_rules! assert_references { 85 ($code:literal, $position:expr $(,)?) => { 86 assert_references!(TestProject::for_source($code), $position); 87 }; 88 89 (($module_name:literal, $module_src:literal), $code:literal, $position:expr $(,)?) => { 90 assert_references!( 91 TestProject::for_source($code).add_module($module_name, $module_src), 92 $position 93 ); 94 }; 95 96 ($project:expr, $position:expr $(,)?) => { 97 let project = $project; 98 let src = project.src; 99 let position = $position.find_position(src); 100 let result = find_references(&project, position).expect("References not found"); 101 102 let mut output = String::new(); 103 for (name, src) in project.root_package_modules.iter() { 104 output.push_str(&format!( 105 "-- {name}.gleam\n{}\n\n", 106 show_references(src, None, result.get(*name).unwrap_or(&Vec::new())) 107 )); 108 } 109 output.push_str(&format!( 110 "-- app.gleam\n{}", 111 show_references( 112 src, 113 Some(position), 114 result.get("app").unwrap_or(&Vec::new()) 115 ) 116 )); 117 118 insta::assert_snapshot!(insta::internals::AutoName, output, src); 119 }; 120} 121 122macro_rules! assert_no_references { 123 ($code:literal, $position:expr $(,)?) => { 124 let project = TestProject::for_source($code); 125 assert_no_references!(&project, $position); 126 }; 127 128 ($project:expr, $position:expr $(,)?) => { 129 let src = $project.src; 130 let position = $position.find_position(src); 131 let result = find_references($project, position); 132 assert_eq!(result, None); 133 }; 134} 135 136#[test] 137fn references_for_local_variable() { 138 assert_references!( 139 " 140pub fn main() { 141 let wibble = 10 142 let wobble = wibble + 1 143 wibble + wobble 144} 145", 146 find_position_of("wibble").nth_occurrence(2), 147 ); 148} 149 150#[test] 151fn references_for_local_variable_from_definition() { 152 assert_references!( 153 " 154pub fn main() { 155 let wibble = 10 156 let wobble = wibble + 1 157 wibble + wobble 158} 159", 160 find_position_of("wibble"), 161 ); 162} 163 164#[test] 165fn references_for_private_function() { 166 assert_references!( 167 " 168fn wibble() { 169 wibble() 170} 171 172pub fn main() { 173 let _ = wibble() 174 wibble() + 4 175} 176 177fn wobble() { 178 wibble() || wobble() 179} 180", 181 find_position_of("wibble"), 182 ); 183} 184 185#[test] 186fn references_for_private_function_from_reference() { 187 assert_references!( 188 " 189fn wibble() { 190 wibble() 191} 192 193pub fn main() { 194 let _ = wibble() 195 wibble() + 4 196} 197 198fn wobble() { 199 wibble() || wobble() 200} 201", 202 find_position_of("wibble").nth_occurrence(2), 203 ); 204} 205 206#[test] 207fn references_for_public_function() { 208 assert_references!( 209 ( 210 "mod", 211 " 212import app.{wibble} 213 214fn wobble() { 215 app.wibble() 216} 217 218fn other() { 219 wibble() 220} 221" 222 ), 223 " 224pub fn wibble() { 225 wibble() 226} 227", 228 find_position_of("wibble").nth_occurrence(2), 229 ); 230} 231 232#[test] 233fn references_for_function_from_qualified_reference() { 234 assert_references!( 235 ( 236 "mod", 237 " 238pub fn wibble() { 239 wibble() 240} 241" 242 ), 243 " 244import mod 245 246pub fn main() { 247 let value = mod.wibble() 248 mod.wibble() 249 value 250} 251", 252 find_position_of("wibble"), 253 ); 254} 255 256#[test] 257fn references_for_function_from_unqualified_reference() { 258 assert_references!( 259 ( 260 "mod", 261 " 262pub fn wibble() { 263 wibble() 264} 265" 266 ), 267 " 268import mod.{wibble} 269 270pub fn main() { 271 let value = wibble() 272 mod.wibble() 273 value 274} 275", 276 find_position_of("wibble()"), 277 ); 278} 279 280#[test] 281fn references_for_function_from_unqualified_aliased_reference() { 282 assert_references!( 283 ( 284 "mod", 285 " 286pub fn wibble() { 287 wibble() 288} 289" 290 ), 291 " 292import mod.{wibble as wobble} 293 294pub fn main() { 295 let value = wobble() 296 mod.wibble() 297 value 298} 299", 300 find_position_of("wobble()"), 301 ); 302} 303 304#[test] 305fn references_for_function_from_import() { 306 assert_references!( 307 ( 308 "mod", 309 " 310pub fn wibble() { 311 wibble() 312} 313" 314 ), 315 " 316import mod.{wibble} 317 318pub fn main() { 319 let value = wibble() 320 mod.wibble() 321 value 322} 323", 324 find_position_of("wibble"), 325 ); 326} 327 328#[test] 329fn references_for_function_from_import_alias() { 330 assert_references!( 331 ( 332 "mod", 333 " 334pub fn wibble() { 335 wibble() 336} 337" 338 ), 339 " 340import mod.{wibble as wobble} 341 342pub fn main() { 343 let value = wobble() 344 mod.wibble() 345 value 346} 347", 348 find_position_of("wobble"), 349 ); 350} 351 352#[test] 353fn references_for_private_constant() { 354 assert_references!( 355 " 356const wibble = 10 357 358pub fn main() { 359 let _ = wibble 360 wibble + 4 361} 362 363fn wobble() { 364 wibble + wobble() 365} 366", 367 find_position_of("wibble"), 368 ); 369} 370 371#[test] 372fn references_for_private_constant_from_reference() { 373 assert_references!( 374 " 375const wibble = 10 376 377pub fn main() { 378 let _ = wibble 379 wibble + 4 380} 381 382fn wobble() { 383 wibble + wobble() 384} 385", 386 find_position_of("wibble").nth_occurrence(2), 387 ); 388} 389 390#[test] 391fn references_for_public_constant() { 392 assert_references!( 393 ( 394 "mod", 395 " 396import app.{wibble} 397 398fn wobble() { 399 app.wibble 400} 401 402fn other() { 403 wibble 404} 405" 406 ), 407 " 408pub const wibble = 10 409 410pub fn main() { 411 wibble 412} 413", 414 find_position_of("wibble").nth_occurrence(2), 415 ); 416} 417 418#[test] 419fn references_for_constant_from_qualified_reference() { 420 assert_references!( 421 ( 422 "mod", 423 " 424pub const wibble = 10 425 426fn wobble() { 427 wibble 428} 429" 430 ), 431 " 432import mod 433 434pub fn main() { 435 let value = mod.wibble 436 mod.wibble + value 437} 438", 439 find_position_of("wibble"), 440 ); 441} 442 443#[test] 444fn references_for_constant_from_unqualified_reference() { 445 assert_references!( 446 ( 447 "mod", 448 " 449pub const wibble = 10 450 451fn wobble() { 452 wibble 453} 454" 455 ), 456 " 457import mod.{wibble} 458 459pub fn main() { 460 let value = mod.wibble 461 wibble + value 462} 463", 464 find_position_of("wibble +"), 465 ); 466} 467 468#[test] 469fn references_for_constant_from_unqualified_aliased_referene() { 470 assert_references!( 471 ( 472 "mod", 473 " 474pub const wibble = 10 475 476fn wobble() { 477 wibble 478} 479" 480 ), 481 " 482import mod.{wibble as wobble} 483 484pub fn main() { 485 let value = mod.wibble 486 wobble + value 487} 488", 489 find_position_of("wobble +"), 490 ); 491} 492 493#[test] 494fn references_for_constant_from_import() { 495 assert_references!( 496 ( 497 "mod", 498 " 499pub const wibble = 10 500 501fn wobble() { 502 wibble 503} 504" 505 ), 506 " 507import mod.{wibble} 508 509pub fn main() { 510 let value = mod.wibble 511 wibble + value 512} 513", 514 find_position_of("wibble"), 515 ); 516} 517 518#[test] 519fn references_for_constant_from_import_alias() { 520 assert_references!( 521 ( 522 "mod", 523 " 524pub const wibble = 10 525 526fn wobble() { 527 wibble 528} 529" 530 ), 531 " 532import mod.{wibble as wobble} 533 534pub fn main() { 535 let value = mod.wibble 536 wobble + value 537} 538", 539 find_position_of("wobble"), 540 ); 541} 542 543#[test] 544fn references_for_private_type_variant() { 545 assert_references!( 546 " 547type Wibble { Wibble } 548 549fn main() { 550 let _ = Wibble 551 Wibble 552} 553 554fn wobble() { 555 Wibble 556 wobble() 557} 558", 559 find_position_of("Wibble }"), 560 ); 561} 562 563#[test] 564fn references_for_private_type_variant_from_reference() { 565 assert_references!( 566 " 567type Wibble { Wibble } 568 569fn main() { 570 let _ = Wibble 571 Wibble 572} 573 574fn wobble() { 575 Wibble 576 wobble() 577} 578", 579 find_position_of(" = Wibble").under_char('W'), 580 ); 581} 582 583#[test] 584fn references_for_public_type_variant() { 585 assert_references!( 586 ( 587 "mod", 588 " 589import app.{Wibble} 590 591fn wobble() { 592 app.Wibble 593} 594 595fn other() { 596 Wibble 597} 598" 599 ), 600 " 601pub type Wibble { Wibble } 602 603pub fn main() { 604 Wibble 605} 606", 607 find_position_of("Wibble }"), 608 ); 609} 610 611#[test] 612fn references_for_type_variant_from_qualified_reference() { 613 assert_references!( 614 ( 615 "mod", 616 " 617pub type Wibble { Wibble } 618 619fn wobble() { 620 Wibble 621} 622" 623 ), 624 " 625import mod 626 627pub fn main() { 628 let value = mod.Wibble 629 mod.Wibble 630 value 631} 632", 633 find_position_of("Wibble"), 634 ); 635} 636 637#[test] 638fn references_for_type_variant_from_unqualified_reference() { 639 assert_references!( 640 ( 641 "mod", 642 " 643pub type Wibble { Wibble } 644 645fn wobble() { 646 Wibble 647} 648" 649 ), 650 " 651import mod.{Wibble} 652 653pub fn main() { 654 let value = mod.Wibble 655 Wibble 656} 657", 658 find_position_of("Wibble").nth_occurrence(3), 659 ); 660} 661 662#[test] 663fn references_for_type_variant_from_unqualified_aliased_reference() { 664 assert_references!( 665 ( 666 "mod", 667 " 668pub type Wibble { Wibble } 669 670fn wobble() { 671 Wibble 672} 673" 674 ), 675 " 676import mod.{Wibble as Wobble} 677 678pub fn main() { 679 let value = mod.Wibble 680 Wobble 681} 682", 683 find_position_of("Wobble").nth_occurrence(2), 684 ); 685} 686 687#[test] 688fn references_for_type_variant_from_import() { 689 assert_references!( 690 ( 691 "mod", 692 " 693pub type Wibble { Wibble } 694 695fn wobble() { 696 Wibble 697} 698" 699 ), 700 " 701import mod.{Wibble} 702 703pub fn main() { 704 let value = mod.Wibble 705 Wibble 706} 707", 708 find_position_of("Wibble"), 709 ); 710} 711 712#[test] 713fn references_for_type_variant_from_import_alias() { 714 assert_references!( 715 ( 716 "mod", 717 " 718pub type Wibble { Wibble } 719 720fn wobble() { 721 Wibble 722} 723" 724 ), 725 " 726import mod.{Wibble as Wobble} 727 728pub fn main() { 729 let value = mod.Wibble 730 Wobble 731} 732", 733 find_position_of("Wobble"), 734 ); 735} 736 737#[test] 738fn no_references_for_keyword() { 739 assert_no_references!( 740 " 741pub fn wibble() { 742 todo 743} 744", 745 find_position_of("fn") 746 ); 747} 748 749#[test] 750fn references_for_aliased_value() { 751 assert_references!( 752 ( 753 "mod", 754 " 755import app.{Wibble as Wobble} 756 757fn wobble() { 758 Wobble 759} 760" 761 ), 762 " 763pub type Wibble { Wibble } 764 765pub fn main() { 766 Wibble 767} 768", 769 find_position_of("Wibble").nth_occurrence(2), 770 ); 771} 772 773#[test] 774fn references_for_aliased_const() { 775 assert_references!( 776 ( 777 "mod", 778 " 779import app.{wibble as other} 780 781fn wobble() { 782 other 783} 784" 785 ), 786 " 787pub const wibble = 123 788 789pub fn main() { 790 wibble 791} 792", 793 find_position_of("wibble").nth_occurrence(2), 794 ); 795} 796 797#[test] 798fn references_for_aliased_function() { 799 assert_references!( 800 ( 801 "mod", 802 " 803import app.{wibble as other} 804 805fn wobble() { 806 other() 807} 808" 809 ), 810 " 811pub fn wibble() { 812 123 813} 814 815pub fn main() { 816 wibble() 817} 818", 819 find_position_of("wibble").nth_occurrence(2), 820 ); 821} 822 823#[test] 824fn references_for_private_type() { 825 assert_references!( 826 " 827type Wibble { Wibble } 828 829fn main() -> Wibble { 830 todo 831} 832 833fn wobble(w: Wibble) { 834 todo 835} 836", 837 find_position_of("Wibble"), 838 ); 839} 840 841#[test] 842fn references_for_private_type_from_reference() { 843 assert_references!( 844 " 845type Wibble { Wibble } 846 847fn main() -> Wibble { 848 todo 849} 850 851fn wobble(w: Wibble) { 852 todo 853} 854", 855 find_position_of("-> Wibble").under_char('W'), 856 ); 857} 858 859#[test] 860fn references_for_public_type() { 861 assert_references!( 862 ( 863 "mod", 864 " 865import app.{type Wibble} 866 867fn wobble() -> Wibble { 868 todo 869} 870 871fn other(w: app.Wibble) { 872 todo 873} 874" 875 ), 876 " 877pub type Wibble { Wibble } 878 879pub fn main() -> Wibble { 880 todo 881} 882", 883 find_position_of("Wibble"), 884 ); 885} 886 887#[test] 888fn references_for_type_from_qualified_reference() { 889 assert_references!( 890 ( 891 "mod", 892 " 893pub type Wibble { Wibble } 894 895fn wobble() -> Wibble { 896 todo 897} 898" 899 ), 900 " 901import mod 902 903pub fn main() -> mod.Wibble { 904 let _: mod.Wibble = todo 905} 906", 907 find_position_of("Wibble"), 908 ); 909} 910 911#[test] 912fn references_for_type_from_unqualified_reference() { 913 assert_references!( 914 ( 915 "mod", 916 " 917pub type Wibble { Wibble } 918 919fn wobble() -> Wibble { 920 todo 921} 922" 923 ), 924 " 925import mod.{type Wibble} 926 927pub fn main() -> Wibble { 928 let _: mod.Wibble = todo 929} 930", 931 find_position_of("Wibble").nth_occurrence(2), 932 ); 933} 934 935#[test] 936fn references_for_type_from_unqualified_aliased_reference() { 937 assert_references!( 938 ( 939 "mod", 940 " 941pub type Wibble { Wibble } 942 943fn wobble() -> Wibble { 944 todo 945} 946" 947 ), 948 " 949import mod.{type Wibble as Wobble} 950 951pub fn main() -> Wobble { 952 let _: mod.Wibble = todo 953} 954", 955 find_position_of("-> Wobble").under_char('W'), 956 ); 957} 958 959#[test] 960fn references_for_type_from_import() { 961 assert_references!( 962 ( 963 "mod", 964 " 965pub type Wibble { Wibble } 966 967fn wobble() -> Wibble { 968 todo 969} 970" 971 ), 972 " 973import mod.{type Wibble} 974 975pub fn main() -> Wibble { 976 let _: mod.Wibble = todo 977} 978", 979 find_position_of("Wibble"), 980 ); 981} 982 983#[test] 984fn references_for_type_from_import_alias() { 985 assert_references!( 986 ( 987 "mod", 988 " 989pub type Wibble { Wibble } 990 991fn wobble() -> Wibble { 992 todo 993} 994" 995 ), 996 " 997import mod.{type Wibble as Wobble} 998 999pub fn main() -> Wobble { 1000 let _: mod.Wibble = todo 1001} 1002", 1003 find_position_of("Wobble"), 1004 ); 1005} 1006 1007#[test] 1008fn references_for_aliased_type() { 1009 assert_references!( 1010 ( 1011 "mod", 1012 " 1013import app.{type Wibble as Wobble} 1014 1015fn wobble() -> Wobble { 1016 todo 1017} 1018 1019fn other(w: app.Wibble) { 1020 todo 1021} 1022" 1023 ), 1024 " 1025pub type Wibble { Wibble } 1026 1027pub fn main() -> Wibble { 1028 todo 1029} 1030", 1031 find_position_of("-> Wibble").under_char('W'), 1032 ); 1033} 1034 1035#[test] 1036fn references_for_type_from_let_annotation() { 1037 assert_references!( 1038 ( 1039 "mod", 1040 " 1041pub type Wibble { Wibble } 1042 1043fn wobble() -> Wibble { 1044 todo 1045} 1046" 1047 ), 1048 " 1049import mod.{type Wibble} 1050 1051pub fn main() -> Wibble { 1052 let _: mod.Wibble = todo 1053} 1054", 1055 find_position_of("mod.Wibble").under_char('W'), 1056 ); 1057} 1058 1059#[test] 1060fn references_for_prefix_string_suffix_variable_in_case() { 1061 assert_references!( 1062 " 1063pub fn main() -> String { 1064 let wibble = \"1-wibble\" 1065 let rest = case wibble { 1066 \"1\" <> rest -> rest 1067 other -> other 1068 } 1069 rest 1070} 1071", 1072 find_position_of("rest").nth_occurrence(2) 1073 ); 1074} 1075 1076#[test] 1077fn references_for_prefix_string_suffix_variable_in_case_triggered_from_usage() { 1078 assert_references!( 1079 " 1080pub fn main() -> String { 1081 let wibble = \"1-wibble\" 1082 let rest = case wibble { 1083 \"1\" <> rest -> rest 1084 other -> other 1085 } 1086 rest 1087} 1088", 1089 find_position_of("rest").nth_occurrence(3) 1090 ); 1091} 1092 1093#[test] 1094fn references_for_prefix_string_suffix_variable_with_alternative_definition_in_case() { 1095 assert_references!( 1096 " 1097pub fn main() -> String { 1098 let wibble = \"1-wibble\" 1099 let rest = case wibble { 1100 \"1\" <> rest | \"2\" <> rest -> rest 1101 other -> other 1102 } 1103 rest 1104} 1105", 1106 find_position_of("rest").nth_occurrence(2), 1107 ); 1108} 1109 1110#[test] 1111fn references_for_prefix_string_suffix_variable_with_alternative_definition_triggered_from_second_pattern() 1112 { 1113 assert_references!( 1114 " 1115pub fn main() -> String { 1116 let wibble = \"1-wibble\" 1117 let rest = case wibble { 1118 \"1\" <> rest | \"2\" <> rest -> rest 1119 other -> other 1120 } 1121 rest 1122} 1123", 1124 find_position_of("rest").nth_occurrence(3), 1125 ); 1126} 1127 1128#[test] 1129fn references_for_prefix_string_suffix_variable_with_alternative_definition_triggered_from_usage() { 1130 assert_references!( 1131 " 1132pub fn main() -> String { 1133 let wibble = \"1-wibble\" 1134 let rest = case wibble { 1135 \"1\" <> rest | \"2\" <> rest -> rest 1136 other -> other 1137 } 1138 rest 1139} 1140", 1141 find_position_of("rest").nth_occurrence(4), 1142 ); 1143} 1144 1145#[test] 1146fn references_for_prefix_string_suffix_variable_in_let_assert() { 1147 assert_references!( 1148 " 1149pub fn main() -> String { 1150 let assert \"1\" <> rest = \"1-wibble\" 1151 rest 1152} 1153", 1154 find_position_of("rest").nth_occurrence(1), 1155 ); 1156} 1157 1158#[test] 1159fn references_for_prefix_string_suffix_variable_in_let_assert_triggered_from_usage() { 1160 assert_references!( 1161 " 1162pub fn main() -> String { 1163 let assert \"1\" <> rest = \"1-wibble\" 1164 rest 1165} 1166", 1167 find_position_of("rest").nth_occurrence(2), 1168 ); 1169} 1170 1171#[test] 1172fn references_for_prefix_string_alias_in_case() { 1173 assert_references!( 1174 " 1175pub fn main() -> String { 1176 let wibble = \"1-wibble\" 1177 let digit = case wibble { 1178 \"1\" as digit <> _rest -> digit 1179 other -> other 1180 } 1181 digit 1182} 1183", 1184 find_position_of("digit").nth_occurrence(2) 1185 ); 1186} 1187 1188#[test] 1189fn references_for_prefix_string_alias_in_case_triggered_from_usage() { 1190 assert_references!( 1191 " 1192pub fn main() -> String { 1193 let wibble = \"1-wibble\" 1194 let digit = case wibble { 1195 \"1\" as digit <> _rest -> digit 1196 other -> other 1197 } 1198 digit 1199} 1200", 1201 find_position_of("digit").nth_occurrence(3) 1202 ); 1203} 1204 1205#[test] 1206fn references_for_prefix_string_alias_with_alternative_definitions_in_case() { 1207 assert_references!( 1208 " 1209pub fn main() -> String { 1210 let wibble = \"1-wibble\" 1211 let digit = case wibble { 1212 \"1\" as digit <> _rest | \"2\" as digit <> _rest -> digit 1213 other -> other 1214 } 1215 digit 1216} 1217", 1218 find_position_of("digit").nth_occurrence(2) 1219 ); 1220} 1221 1222#[test] 1223fn references_for_prefix_string_alias_with_alternative_definitions_triggered_from_second_pattern() { 1224 assert_references!( 1225 " 1226pub fn main() -> String { 1227 let wibble = \"1-wibble\" 1228 let digit = case wibble { 1229 \"1\" as digit <> _rest | \"2\" as digit <> _rest -> digit 1230 other -> other 1231 } 1232 digit 1233} 1234", 1235 find_position_of("digit").nth_occurrence(3) 1236 ); 1237} 1238 1239#[test] 1240fn references_for_prefix_string_alias_with_alternative_definitions_triggered_from_usage() { 1241 assert_references!( 1242 " 1243pub fn main() -> String { 1244 let wibble = \"1-wibble\" 1245 let digit = case wibble { 1246 \"1\" as digit <> _rest | \"2\" as digit <> _rest -> digit 1247 other -> other 1248 } 1249 digit 1250} 1251", 1252 find_position_of("digit").nth_occurrence(4) 1253 ); 1254} 1255 1256#[test] 1257fn references_for_prefix_string_alias_in_let_assert() { 1258 assert_references!( 1259 " 1260pub fn main() -> String { 1261 let assert \"1\" as digit <> _rest = \"1-wibble\" 1262 digit 1263} 1264", 1265 find_position_of("digit").nth_occurrence(1) 1266 ); 1267} 1268 1269#[test] 1270fn references_for_prefix_string_alias_in_let_assert_triggered_from_usage() { 1271 assert_references!( 1272 " 1273pub fn main() -> String { 1274 let assert \"1\" as digit <> _rest = \"1-wibble\" 1275 digit 1276} 1277", 1278 find_position_of("digit").nth_occurrence(2) 1279 ); 1280} 1281 1282#[test] 1283fn references_for_prefix_string_suffix_variable_nested_in_tuple() { 1284 assert_references!( 1285 " 1286fn main() { 1287 case #(\"1-wibble\", 0) { 1288 #(\"1\" <> rest, _) -> rest 1289 _ -> \"\" 1290 } 1291} 1292", 1293 find_position_of("rest").nth_occurrence(1) 1294 ); 1295} 1296 1297#[test] 1298fn references_for_prefix_string_alias_used_in_guard() { 1299 assert_references!( 1300 " 1301fn main() { 1302 case \"1-wibble\" { 1303 \"1\" as digit <> _rest if digit == \"1\" -> digit 1304 _ -> \"\" 1305 } 1306} 1307", 1308 find_position_of("digit").nth_occurrence(1) 1309 ); 1310} 1311 1312#[test] 1313fn references_for_prefix_string_suffix_used_in_guard() { 1314 assert_references!( 1315 " 1316fn main() { 1317 case \"1-wibble\" { 1318 \"1\" <> rest if rest == \"-wibble\" -> rest 1319 _ -> \"\" 1320 } 1321} 1322", 1323 find_position_of("rest").nth_occurrence(1) 1324 ); 1325} 1326 1327#[test] 1328fn references_for_prefix_string_suffix_shadowing_outer_variable() { 1329 assert_references!( 1330 " 1331fn main() { 1332 let rest = \"outer\" 1333 case \"1-wibble\" { 1334 \"1\" <> rest -> rest 1335 _ -> rest 1336 } 1337} 1338", 1339 find_position_of("rest").nth_occurrence(2) 1340 ); 1341} 1342 1343#[test] 1344fn references_for_prefix_string_alias_and_suffix_complex_guard() { 1345 assert_references!( 1346 " 1347fn main() { 1348 case \"1-wibble\" { 1349 \"1\" as digit <> rest if digit == \"1\" && rest == \"-wibble\" -> #(digit, rest) 1350 _ -> #(\"\", \"\") 1351 } 1352} 1353", 1354 find_position_of("digit").nth_occurrence(1) 1355 ); 1356} 1357 1358#[test] 1359fn references_for_local_variable_from_guard() { 1360 assert_references!( 1361 " 1362pub fn main() { 1363 let wibble = True 1364 let wobble = False 1365 case wibble { 1366 True if wobble -> !wibble 1367 False if !wobble -> wibble 1368 _ -> wobble 1369 } 1370} 1371", 1372 find_position_of("wobble").nth_occurrence(2).under_char('o') 1373 ); 1374} 1375 1376#[test] 1377fn references_for_module_select_from_guard() { 1378 assert_references!( 1379 ("mod", "pub const wibble = 10"), 1380 " 1381import mod 1382 1383pub fn main() { 1384 let wibble = True 1385 case wibble { 1386 True if mod.wibble < 5 -> !wibble 1387 False if mod.wibble != 10 -> wibble 1388 _ -> mod.wibble + 1 1389 } 1390} 1391", 1392 find_position_of("mod.wibble").under_char('w') 1393 ); 1394} 1395 1396#[test] 1397fn references_for_invalid_constant_todo_message_still_works() { 1398 assert_references!( 1399 " 1400const wibble = 1 1401const wobble = todo as wibble 1402", 1403 find_position_of("wibble") 1404 ); 1405} 1406 1407#[test] 1408fn references_for_invalid_constant_todo_message_still_works_2() { 1409 assert_references!( 1410 " 1411const wibble = 1 1412const wobble = todo as [wibble] 1413", 1414 find_position_of("wibble") 1415 ); 1416} 1417 1418#[test] 1419fn references_for_record_field() { 1420 assert_references!( 1421 " 1422type Wibble { 1423 Wibble(wibble: Int) 1424} 1425 1426pub fn main() { 1427 let value = Wibble(wibble: 1) 1428 value.wibble 1429} 1430", 1431 find_position_of("value.wibble").under_char('i') 1432 ); 1433} 1434 1435#[test] 1436fn references_for_record_field_in_module_not_importing_the_type_module() { 1437 assert_references!( 1438 TestProject::for_source( 1439 " 1440import wobble 1441 1442pub fn main() { 1443 wobble.make().wibble 1444} 1445" 1446 ) 1447 .add_module("wibble", "pub type Wibble {\n Wibble(wibble: Int)\n}") 1448 .add_module( 1449 "wobble", 1450 "import wibble\n\npub fn make() -> wibble.Wibble {\n wibble.Wibble(wibble: 1)\n}" 1451 ), 1452 find_position_of("().wibble").under_char('b') 1453 ); 1454} 1455 1456#[test] 1457fn references_for_record_field_ignored_by_record_update_spread() { 1458 // https://github.com/gleam-lang/gleam/pull/5533#pullrequestreview-4475156690 1459 assert_references!( 1460 " 1461type Wibble { 1462 Wibble(wibble: Int, wobble: Int) 1463} 1464 1465pub fn main(w: Wibble) { 1466 Wibble(..w, wibble: 2) 1467} 1468", 1469 find_position_of("wobble: Int").under_char('w') 1470 ); 1471} 1472 1473#[test] 1474fn references_for_record_field_ignored_by_constant_record_update_spread() { 1475 assert_references!( 1476 " 1477type Wibble { 1478 Wibble(wibble: Int, wobble: Int) 1479} 1480 1481const base = Wibble(wibble: 1, wobble: 2) 1482 1483const updated = Wibble(..base, wibble: 3) 1484", 1485 find_position_of("wobble: Int").under_char('w') 1486 ); 1487} 1488 1489#[test] 1490fn references_for_record_field_ignored_by_record_update_with_record_access_spread() { 1491 assert_references!( 1492 " 1493type Container { 1494 Container(inner: Wibble) 1495} 1496 1497type Wibble { 1498 Wibble(wibble: Int, wobble: Int) 1499} 1500 1501pub fn main(c: Container) { 1502 Wibble(..c.inner, wibble: 2) 1503} 1504", 1505 find_position_of("wobble: Int").under_char('w') 1506 ); 1507} 1508 1509#[test] 1510fn references_for_record_field_ignored_by_nested_record_update_spread() { 1511 assert_references!( 1512 " 1513type Wibble { 1514 Wibble(wibble: Int, wobble: Int) 1515} 1516 1517pub fn main(w: Wibble) { 1518 Wibble(..Wibble(..w, wibble: 1), wobble: 2) 1519} 1520", 1521 find_position_of("wibble: Int").under_char('w') 1522 ); 1523} 1524 1525#[test] 1526fn references_for_record_field_ignored_by_pipe_into_constructor() { 1527 assert_references!( 1528 " 1529type Wibble { 1530 Wibble(name: Int, age: Int) 1531} 1532 1533pub fn main() { 1534 1 |> Wibble(age: 2) 1535} 1536", 1537 find_position_of("name: Int").under_char('n') 1538 ); 1539} 1540 1541#[test] 1542fn references_for_record_field_ignored_by_pattern_spread() { 1543 assert_references!( 1544 " 1545type Wibble { 1546 Wibble(wibble: Int, wobble: Int) 1547} 1548 1549pub fn main(w: Wibble) { 1550 case w { 1551 Wibble(wibble: a, ..) -> a 1552 } 1553} 1554", 1555 find_position_of("wobble: Int").under_char('w') 1556 ); 1557} 1558 1559#[test] 1560fn references_for_value_from_import_imported_name() { 1561 assert_references!( 1562 ( 1563 "mod", 1564 " 1565pub fn wibble() { 1566 wibble() 1567} 1568" 1569 ), 1570 " 1571import mod.{wibble as wobble} 1572 1573pub fn main() { 1574 let value = wobble() 1575 mod.wibble() 1576 value 1577} 1578", 1579 find_position_of("wibble"), 1580 ); 1581} 1582 1583#[test] 1584fn references_for_value_from_import_as() { 1585 assert_references!( 1586 ( 1587 "mod", 1588 " 1589pub fn wibble() { 1590 wibble() 1591} 1592" 1593 ), 1594 " 1595import mod.{wibble as wobble} 1596 1597pub fn main() { 1598 let value = wobble() 1599 mod.wibble() 1600 value 1601} 1602", 1603 find_position_of("as"), 1604 ); 1605} 1606 1607#[test] 1608fn references_for_value_from_import_alias_name() { 1609 assert_references!( 1610 ( 1611 "mod", 1612 " 1613pub fn wibble() { 1614 wibble() 1615} 1616" 1617 ), 1618 " 1619import mod.{wibble as wobble} 1620 1621pub fn main() { 1622 let value = wobble() 1623 mod.wibble() 1624 value 1625} 1626", 1627 find_position_of("wobble"), 1628 ); 1629} 1630 1631#[test] 1632fn references_for_type_from_import_type() { 1633 assert_references!( 1634 ( 1635 "mod", 1636 " 1637pub type Wibble { Wibble } 1638 1639fn wobble() -> Wibble { 1640 todo 1641} 1642" 1643 ), 1644 " 1645import mod.{type Wibble as Wobble} 1646 1647pub fn main() -> Wobble { 1648 let _: mod.Wibble = todo 1649} 1650", 1651 find_position_of("type"), 1652 ); 1653} 1654 1655#[test] 1656fn references_for_type_from_import_imported_name() { 1657 assert_references!( 1658 ( 1659 "mod", 1660 " 1661pub type Wibble { Wibble } 1662 1663fn wobble() -> Wibble { 1664 todo 1665} 1666" 1667 ), 1668 " 1669import mod.{type Wibble as Wobble} 1670 1671pub fn main() -> Wobble { 1672 let _: mod.Wibble = todo 1673} 1674", 1675 find_position_of("Wibble"), 1676 ); 1677} 1678 1679#[test] 1680fn references_for_type_from_import_as() { 1681 assert_references!( 1682 ( 1683 "mod", 1684 " 1685pub type Wibble { Wibble } 1686 1687fn wobble() -> Wibble { 1688 todo 1689} 1690" 1691 ), 1692 " 1693import mod.{type Wibble as Wobble} 1694 1695pub fn main() -> Wobble { 1696 let _: mod.Wibble = todo 1697} 1698", 1699 find_position_of("as"), 1700 ); 1701} 1702 1703#[test] 1704fn references_for_type_from_import_clias_name() { 1705 assert_references!( 1706 ( 1707 "mod", 1708 " 1709pub type Wibble { Wibble } 1710 1711fn wobble() -> Wibble { 1712 todo 1713} 1714" 1715 ), 1716 " 1717import mod.{type Wibble as Wobble} 1718 1719pub fn main() -> Wobble { 1720 let _: mod.Wibble = todo 1721} 1722", 1723 find_position_of("Wobble"), 1724 ); 1725}