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

Configure Feed

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

gleam / compiler-core / src / ast / tests.rs
30 kB 1132 lines
1use std::sync::Arc; 2 3use camino::Utf8PathBuf; 4 5use crate::analyse::TargetSupport; 6use crate::build::{ExpressionPosition, Origin, Target}; 7use crate::config::PackageConfig; 8use crate::line_numbers::LineNumbers; 9use crate::type_::error::{VariableDeclaration, VariableOrigin, VariableSyntax}; 10use crate::type_::expression::{FunctionDefinition, Purity}; 11use crate::type_::{Deprecation, PRELUDE_MODULE_NAME, Problems}; 12use crate::warning::WarningEmitter; 13use crate::{ 14 ast::{SrcSpan, TypedExpr}, 15 build::Located, 16 type_::{ 17 self, AccessorsMap, EnvironmentArguments, ExprTyper, FieldMap, ModuleValueConstructor, 18 RecordAccessor, Type, ValueConstructor, ValueConstructorVariant, 19 }, 20 uid::UniqueIdGenerator, 21 warning::TypeWarningEmitter, 22}; 23 24use super::{Publicity, Statement, TypedModule, TypedStatement}; 25 26fn compile_module(src: &str) -> TypedModule { 27 use crate::type_::build_prelude; 28 let parsed = 29 crate::parse::parse_module(Utf8PathBuf::from("test/path"), src, &WarningEmitter::null()) 30 .expect("syntax error"); 31 let ast = parsed.module; 32 let ids = UniqueIdGenerator::new(); 33 let mut config = PackageConfig::default(); 34 config.name = "thepackage".into(); 35 let mut modules = im::HashMap::new(); 36 // DUPE: preludeinsertion 37 // TODO: Currently we do this here and also in the tests. It would be better 38 // to have one place where we create all this required state for use in each 39 // place. 40 let _ = modules.insert(PRELUDE_MODULE_NAME.into(), build_prelude(&ids)); 41 let line_numbers = LineNumbers::new(src); 42 let mut config = PackageConfig::default(); 43 config.name = "thepackage".into(); 44 45 crate::analyse::ModuleAnalyzerConstructor::<()> { 46 target: Target::Erlang, 47 ids: &ids, 48 origin: Origin::Src, 49 importable_modules: &modules, 50 warnings: &TypeWarningEmitter::null(), 51 direct_dependencies: &std::collections::HashMap::new(), 52 target_support: TargetSupport::Enforced, 53 package_config: &config, 54 } 55 .infer_module(ast, line_numbers, "".into()) 56 .expect("should successfully infer") 57} 58 59fn get_bare_expression(statement: &TypedStatement) -> &TypedExpr { 60 match statement { 61 Statement::Expression(expression) => expression, 62 Statement::Use(_) | Statement::Assignment(_) | Statement::Assert(_) => { 63 panic!("Expected expression, got {statement:?}") 64 } 65 } 66} 67 68fn compile_expression(src: &str) -> TypedStatement { 69 let ast = crate::parse::parse_statement_sequence(src).expect("syntax error"); 70 71 let mut modules = im::HashMap::new(); 72 let ids = UniqueIdGenerator::new(); 73 // DUPE: preludeinsertion 74 // TODO: Currently we do this here and also in the tests. It would be better 75 // to have one place where we create all this required state for use in each 76 // place. 77 let _ = modules.insert(PRELUDE_MODULE_NAME.into(), type_::build_prelude(&ids)); 78 let mut environment = EnvironmentArguments { 79 ids, 80 current_package: "thepackage".into(), 81 gleam_version: None, 82 current_module: "mymod".into(), 83 target: Target::Erlang, 84 importable_modules: &modules, 85 target_support: TargetSupport::Enforced, 86 current_origin: Origin::Src, 87 } 88 .build(); 89 90 // Insert a cat record to use in the tests 91 let cat_type = Arc::new(Type::Named { 92 publicity: Publicity::Public, 93 package: "mypackage".into(), 94 module: "mymod".into(), 95 name: "Cat".into(), 96 args: vec![], 97 inferred_variant: None, 98 }); 99 let variant = ValueConstructorVariant::Record { 100 documentation: Some("wibble".into()), 101 variants_count: 1, 102 name: "Cat".into(), 103 arity: 2, 104 location: SrcSpan { start: 12, end: 15 }, 105 field_map: Some(FieldMap { 106 arity: 2, 107 fields: [("name".into(), 0), ("age".into(), 1)].into(), 108 }), 109 module: "mymod".into(), 110 variant_index: 0, 111 }; 112 environment.insert_variable( 113 "Cat".into(), 114 variant, 115 type_::fn_(vec![type_::string(), type_::int()], cat_type.clone()), 116 Publicity::Public, 117 Deprecation::NotDeprecated, 118 ); 119 120 let accessors = [ 121 ( 122 "name".into(), 123 RecordAccessor { 124 index: 0, 125 label: "name".into(), 126 type_: type_::string(), 127 }, 128 ), 129 ( 130 "age".into(), 131 RecordAccessor { 132 index: 1, 133 label: "age".into(), 134 type_: type_::int(), 135 }, 136 ), 137 ]; 138 139 environment.insert_accessors( 140 "Cat".into(), 141 AccessorsMap { 142 publicity: Publicity::Public, 143 type_: cat_type, 144 shared_accessors: accessors.clone().into(), 145 variant_specific_accessors: vec![accessors.into()], 146 }, 147 ); 148 let mut problems = Problems::new(); 149 ExprTyper::new( 150 &mut environment, 151 FunctionDefinition { 152 has_body: true, 153 has_erlang_external: false, 154 has_javascript_external: false, 155 }, 156 &mut problems, 157 ) 158 .infer_statements(ast) 159 .first() 160 .clone() 161} 162 163#[test] 164fn find_node_todo() { 165 let statement = compile_expression(r#" todo "#); 166 let expr = get_bare_expression(&statement); 167 assert_eq!(expr.find_node(0), None); 168 assert_eq!( 169 expr.find_node(1), 170 Some(Located::Expression { 171 expression: expr, 172 position: ExpressionPosition::Expression 173 }) 174 ); 175 assert_eq!( 176 expr.find_node(4), 177 Some(Located::Expression { 178 expression: expr, 179 position: ExpressionPosition::Expression 180 }) 181 ); 182 assert_eq!( 183 expr.find_node(5), 184 Some(Located::Expression { 185 expression: expr, 186 position: ExpressionPosition::Expression 187 }) 188 ); 189 assert_eq!(expr.find_node(6), None); 190} 191 192#[test] 193fn find_node_todo_with_string() { 194 let statement = compile_expression(r#" todo as "ok" "#); 195 let expr = get_bare_expression(&statement); 196 assert_eq!(expr.find_node(0), None); 197 assert_eq!( 198 expr.find_node(1), 199 Some(Located::Expression { 200 expression: expr, 201 position: ExpressionPosition::Expression 202 }) 203 ); 204 assert_eq!( 205 expr.find_node(12), 206 Some(Located::Expression { 207 expression: expr, 208 position: ExpressionPosition::Expression 209 }) 210 ); 211 assert_eq!( 212 expr.find_node(13), 213 Some(Located::Expression { 214 expression: expr, 215 position: ExpressionPosition::Expression 216 }) 217 ); 218 assert_eq!(expr.find_node(14), None); 219} 220 221#[test] 222fn find_node_string() { 223 let statement = compile_expression(r#" "ok" "#); 224 let expr = get_bare_expression(&statement); 225 assert_eq!(expr.find_node(0), None); 226 assert_eq!( 227 expr.find_node(1), 228 Some(Located::Expression { 229 expression: expr, 230 position: ExpressionPosition::Expression 231 }) 232 ); 233 assert_eq!( 234 expr.find_node(4), 235 Some(Located::Expression { 236 expression: expr, 237 position: ExpressionPosition::Expression 238 }) 239 ); 240 assert_eq!( 241 expr.find_node(5), 242 Some(Located::Expression { 243 expression: expr, 244 position: ExpressionPosition::Expression 245 }) 246 ); 247 assert_eq!(expr.find_node(6), None); 248} 249 250#[test] 251fn find_node_float() { 252 let statement = compile_expression(r#" 1.02 "#); 253 let expr = get_bare_expression(&statement); 254 assert_eq!(expr.find_node(0), None); 255 assert_eq!( 256 expr.find_node(1), 257 Some(Located::Expression { 258 expression: expr, 259 position: ExpressionPosition::Expression 260 }) 261 ); 262 assert_eq!( 263 expr.find_node(4), 264 Some(Located::Expression { 265 expression: expr, 266 position: ExpressionPosition::Expression 267 }) 268 ); 269 assert_eq!( 270 expr.find_node(5), 271 Some(Located::Expression { 272 expression: expr, 273 position: ExpressionPosition::Expression 274 }) 275 ); 276 assert_eq!(expr.find_node(6), None); 277} 278 279#[test] 280fn find_node_int() { 281 let statement = compile_expression(r#" 1302 "#); 282 let expr = get_bare_expression(&statement); 283 assert_eq!(expr.find_node(0), None); 284 assert_eq!( 285 expr.find_node(1), 286 Some(Located::Expression { 287 expression: expr, 288 position: ExpressionPosition::Expression 289 }) 290 ); 291 assert_eq!( 292 expr.find_node(4), 293 Some(Located::Expression { 294 expression: expr, 295 position: ExpressionPosition::Expression 296 }) 297 ); 298 assert_eq!( 299 expr.find_node(5), 300 Some(Located::Expression { 301 expression: expr, 302 position: ExpressionPosition::Expression 303 }) 304 ); 305 assert_eq!(expr.find_node(6), None); 306} 307 308#[test] 309fn find_node_var() { 310 let statement = compile_expression( 311 r#"{let wibble = 1 312wibble}"#, 313 ); 314 let expr = get_bare_expression(&statement); 315 316 let int1 = TypedExpr::Int { 317 location: SrcSpan { start: 14, end: 15 }, 318 value: "1".into(), 319 int_value: 1.into(), 320 type_: type_::int(), 321 }; 322 323 let var = TypedExpr::Var { 324 location: SrcSpan { start: 16, end: 22 }, 325 constructor: ValueConstructor { 326 deprecation: Deprecation::NotDeprecated, 327 publicity: Publicity::Private, 328 variant: ValueConstructorVariant::LocalVariable { 329 location: SrcSpan { start: 5, end: 11 }, 330 origin: VariableOrigin { 331 syntax: VariableSyntax::Variable("wibble".into()), 332 declaration: VariableDeclaration::LetPattern, 333 }, 334 }, 335 type_: type_::int(), 336 }, 337 name: "wibble".into(), 338 }; 339 340 assert_eq!( 341 expr.find_node(15), 342 Some(Located::Expression { 343 expression: &int1, 344 position: ExpressionPosition::Expression 345 }) 346 ); 347 assert_eq!( 348 expr.find_node(16), 349 Some(Located::Expression { 350 expression: &var, 351 position: ExpressionPosition::Expression 352 }) 353 ); 354 assert_eq!( 355 expr.find_node(21), 356 Some(Located::Expression { 357 expression: &var, 358 position: ExpressionPosition::Expression 359 }) 360 ); 361 assert_eq!( 362 expr.find_node(22), 363 Some(Located::Expression { 364 expression: &var, 365 position: ExpressionPosition::Expression 366 }) 367 ); 368} 369 370#[test] 371fn find_node_sequence() { 372 let block = compile_expression(r#"{ 1 2 3 }"#); 373 assert!(block.find_node(0).is_none()); 374 assert!(block.find_node(1).is_none()); 375 assert!(block.find_node(2).is_some()); 376 assert!(block.find_node(3).is_some()); 377 assert!(block.find_node(4).is_some()); 378 assert!(block.find_node(5).is_some()); 379 assert!(block.find_node(6).is_some()); 380 assert!(block.find_node(7).is_some()); 381} 382 383#[test] 384fn find_node_list() { 385 let statement = compile_expression(r#"[1, 2, 3]"#); 386 let list = get_bare_expression(&statement); 387 388 let int1 = TypedExpr::Int { 389 location: SrcSpan { start: 1, end: 2 }, 390 type_: type_::int(), 391 value: "1".into(), 392 int_value: 1.into(), 393 }; 394 let int2 = TypedExpr::Int { 395 location: SrcSpan { start: 4, end: 5 }, 396 type_: type_::int(), 397 value: "2".into(), 398 int_value: 2.into(), 399 }; 400 let int3 = TypedExpr::Int { 401 location: SrcSpan { start: 7, end: 8 }, 402 type_: type_::int(), 403 value: "3".into(), 404 int_value: 3.into(), 405 }; 406 407 assert_eq!( 408 list.find_node(0), 409 Some(Located::Expression { 410 expression: list, 411 position: ExpressionPosition::Expression 412 }) 413 ); 414 assert_eq!( 415 list.find_node(1), 416 Some(Located::Expression { 417 expression: &int1, 418 position: ExpressionPosition::Expression 419 }) 420 ); 421 assert_eq!( 422 list.find_node(2), 423 Some(Located::Expression { 424 expression: &int1, 425 position: ExpressionPosition::Expression 426 }) 427 ); 428 assert_eq!( 429 list.find_node(3), 430 Some(Located::Expression { 431 expression: list, 432 position: ExpressionPosition::Expression 433 }) 434 ); 435 assert_eq!( 436 list.find_node(4), 437 Some(Located::Expression { 438 expression: &int2, 439 position: ExpressionPosition::Expression 440 }) 441 ); 442 assert_eq!( 443 list.find_node(5), 444 Some(Located::Expression { 445 expression: &int2, 446 position: ExpressionPosition::Expression 447 }) 448 ); 449 assert_eq!( 450 list.find_node(6), 451 Some(Located::Expression { 452 expression: list, 453 position: ExpressionPosition::Expression 454 }) 455 ); 456 assert_eq!( 457 list.find_node(7), 458 Some(Located::Expression { 459 expression: &int3, 460 position: ExpressionPosition::Expression 461 }) 462 ); 463 assert_eq!( 464 list.find_node(8), 465 Some(Located::Expression { 466 expression: &int3, 467 position: ExpressionPosition::Expression 468 }) 469 ); 470 assert_eq!( 471 list.find_node(9), 472 Some(Located::Expression { 473 expression: list, 474 position: ExpressionPosition::Expression 475 }) 476 ); 477} 478 479#[test] 480fn find_node_tuple() { 481 let statement = compile_expression(r#"#(1, 2, 3)"#); 482 let tuple = get_bare_expression(&statement); 483 484 let int1 = TypedExpr::Int { 485 location: SrcSpan { start: 2, end: 3 }, 486 type_: type_::int(), 487 value: "1".into(), 488 int_value: 1.into(), 489 }; 490 let int2 = TypedExpr::Int { 491 location: SrcSpan { start: 5, end: 6 }, 492 type_: type_::int(), 493 value: "2".into(), 494 int_value: 2.into(), 495 }; 496 let int3 = TypedExpr::Int { 497 location: SrcSpan { start: 8, end: 9 }, 498 type_: type_::int(), 499 value: "3".into(), 500 int_value: 3.into(), 501 }; 502 503 assert_eq!( 504 tuple.find_node(0), 505 Some(Located::Expression { 506 expression: tuple, 507 position: ExpressionPosition::Expression 508 }) 509 ); 510 assert_eq!( 511 tuple.find_node(1), 512 Some(Located::Expression { 513 expression: tuple, 514 position: ExpressionPosition::Expression 515 }) 516 ); 517 assert_eq!( 518 tuple.find_node(2), 519 Some(Located::Expression { 520 expression: &int1, 521 position: ExpressionPosition::Expression 522 }) 523 ); 524 assert_eq!( 525 tuple.find_node(3), 526 Some(Located::Expression { 527 expression: &int1, 528 position: ExpressionPosition::Expression 529 }) 530 ); 531 assert_eq!( 532 tuple.find_node(4), 533 Some(Located::Expression { 534 expression: tuple, 535 position: ExpressionPosition::Expression 536 }) 537 ); 538 assert_eq!( 539 tuple.find_node(5), 540 Some(Located::Expression { 541 expression: &int2, 542 position: ExpressionPosition::Expression 543 }) 544 ); 545 assert_eq!( 546 tuple.find_node(6), 547 Some(Located::Expression { 548 expression: &int2, 549 position: ExpressionPosition::Expression 550 }) 551 ); 552 assert_eq!( 553 tuple.find_node(7), 554 Some(Located::Expression { 555 expression: tuple, 556 position: ExpressionPosition::Expression 557 }) 558 ); 559 assert_eq!( 560 tuple.find_node(8), 561 Some(Located::Expression { 562 expression: &int3, 563 position: ExpressionPosition::Expression 564 }) 565 ); 566 assert_eq!( 567 tuple.find_node(9), 568 Some(Located::Expression { 569 expression: &int3, 570 position: ExpressionPosition::Expression 571 }) 572 ); 573 assert_eq!( 574 tuple.find_node(10), 575 Some(Located::Expression { 576 expression: tuple, 577 position: ExpressionPosition::Expression 578 }) 579 ); 580} 581 582#[test] 583fn find_node_binop() { 584 let statement = compile_expression(r#"1 + 2"#); 585 let expr = get_bare_expression(&statement); 586 assert!(expr.find_node(0).is_some()); 587 assert!(expr.find_node(1).is_some()); 588 assert!(expr.find_node(2).is_none()); 589 assert!(expr.find_node(3).is_none()); 590 assert!(expr.find_node(4).is_some()); 591 assert!(expr.find_node(5).is_some()); 592} 593 594#[test] 595fn find_node_tuple_index() { 596 let statement = compile_expression(r#"#(1).0"#); 597 let expr = get_bare_expression(&statement); 598 599 let int = TypedExpr::Int { 600 location: SrcSpan { start: 2, end: 3 }, 601 value: "1".into(), 602 int_value: 1.into(), 603 type_: type_::int(), 604 }; 605 606 assert_eq!( 607 expr.find_node(2), 608 Some(Located::Expression { 609 expression: &int, 610 position: ExpressionPosition::Expression 611 }) 612 ); 613 assert_eq!( 614 expr.find_node(5), 615 Some(Located::Expression { 616 expression: expr, 617 position: ExpressionPosition::Expression 618 }) 619 ); 620 assert_eq!( 621 expr.find_node(6), 622 Some(Located::Expression { 623 expression: expr, 624 position: ExpressionPosition::Expression 625 }) 626 ); 627} 628 629#[test] 630fn find_node_module_select() { 631 let expr = TypedExpr::ModuleSelect { 632 location: SrcSpan { start: 1, end: 4 }, 633 field_start: 2, 634 type_: type_::int(), 635 label: "label".into(), 636 module_name: "name".into(), 637 module_alias: "alias".into(), 638 constructor: ModuleValueConstructor::Fn { 639 module: "module".into(), 640 name: "function".into(), 641 external_erlang: None, 642 external_javascript: None, 643 location: SrcSpan { start: 1, end: 55 }, 644 documentation: None, 645 field_map: None, 646 purity: Purity::Pure, 647 }, 648 }; 649 650 assert_eq!(expr.find_node(0), None); 651 assert_eq!( 652 expr.find_node(1), 653 Some(Located::ModuleName { 654 location: SrcSpan::new(1, 1), 655 name: &"name".into(), 656 layer: super::Layer::Value 657 }) 658 ); 659 assert_eq!( 660 expr.find_node(2), 661 Some(Located::Expression { 662 expression: &expr, 663 position: ExpressionPosition::Expression 664 }) 665 ); 666 assert_eq!( 667 expr.find_node(3), 668 Some(Located::Expression { 669 expression: &expr, 670 position: ExpressionPosition::Expression 671 }) 672 ); 673} 674 675#[test] 676fn find_node_fn() { 677 let statement = compile_expression("fn() { 1 }"); 678 let expr = get_bare_expression(&statement); 679 680 let int = TypedExpr::Int { 681 location: SrcSpan { start: 7, end: 8 }, 682 value: "1".into(), 683 int_value: 1.into(), 684 type_: type_::int(), 685 }; 686 687 assert_eq!( 688 expr.find_node(0), 689 Some(Located::Expression { 690 expression: expr, 691 position: ExpressionPosition::Expression 692 }) 693 ); 694 assert_eq!( 695 expr.find_node(6), 696 Some(Located::Expression { 697 expression: expr, 698 position: ExpressionPosition::Expression 699 }) 700 ); 701 assert_eq!( 702 expr.find_node(7), 703 Some(Located::Expression { 704 expression: &int, 705 position: ExpressionPosition::Expression 706 }) 707 ); 708 assert_eq!( 709 expr.find_node(8), 710 Some(Located::Expression { 711 expression: &int, 712 position: ExpressionPosition::Expression 713 }) 714 ); 715 assert_eq!( 716 expr.find_node(9), 717 Some(Located::Expression { 718 expression: expr, 719 position: ExpressionPosition::Expression 720 }) 721 ); 722 assert_eq!( 723 expr.find_node(10), 724 Some(Located::Expression { 725 expression: expr, 726 position: ExpressionPosition::Expression 727 }) 728 ); 729} 730 731#[test] 732fn find_node_call() { 733 let statement = compile_expression("fn(_, _) { 1 }(1, 2)"); 734 let expr = get_bare_expression(&statement); 735 736 let return_ = TypedExpr::Int { 737 location: SrcSpan { start: 11, end: 12 }, 738 value: "1".into(), 739 int_value: 1.into(), 740 type_: type_::int(), 741 }; 742 743 let arg1 = TypedExpr::Int { 744 location: SrcSpan { start: 15, end: 16 }, 745 value: "1".into(), 746 int_value: 1.into(), 747 type_: type_::int(), 748 }; 749 750 let arg2 = TypedExpr::Int { 751 location: SrcSpan { start: 18, end: 19 }, 752 value: "2".into(), 753 int_value: 2.into(), 754 type_: type_::int(), 755 }; 756 757 let TypedExpr::Call { 758 fun: called_function, 759 args: function_arguments, 760 .. 761 } = expr 762 else { 763 panic!("Expression was not a function call"); 764 }; 765 766 assert_eq!( 767 expr.find_node(11), 768 Some(Located::Expression { 769 expression: &return_, 770 position: ExpressionPosition::Expression 771 }) 772 ); 773 assert_eq!( 774 expr.find_node(15), 775 Some(Located::Expression { 776 expression: &arg1, 777 position: ExpressionPosition::Expression 778 }) 779 ); 780 assert_eq!( 781 expr.find_node(16), 782 Some(Located::Expression { 783 expression: &arg1, 784 position: ExpressionPosition::ArgumentOrLabel { 785 called_function, 786 function_arguments 787 } 788 }) 789 ); 790 assert_eq!( 791 expr.find_node(17), 792 Some(Located::Expression { 793 expression: expr, 794 position: ExpressionPosition::Expression 795 }) 796 ); 797 assert_eq!( 798 expr.find_node(18), 799 Some(Located::Expression { 800 expression: &arg2, 801 position: ExpressionPosition::Expression 802 }) 803 ); 804 assert_eq!( 805 expr.find_node(19), 806 Some(Located::Expression { 807 expression: &arg2, 808 position: ExpressionPosition::ArgumentOrLabel { 809 called_function, 810 function_arguments 811 } 812 }) 813 ); 814 assert_eq!( 815 expr.find_node(20), 816 Some(Located::Expression { 817 expression: expr, 818 position: ExpressionPosition::Expression 819 }) 820 ); 821} 822 823#[test] 824fn find_node_record_access() { 825 let statement = compile_expression(r#"Cat("Nubi", 3).name"#); 826 let access = get_bare_expression(&statement); 827 828 let string = TypedExpr::String { 829 location: SrcSpan { start: 4, end: 10 }, 830 value: "Nubi".into(), 831 type_: type_::string(), 832 }; 833 834 let int = TypedExpr::Int { 835 location: SrcSpan { start: 12, end: 13 }, 836 value: "3".into(), 837 int_value: 3.into(), 838 type_: type_::int(), 839 }; 840 841 assert_eq!( 842 access.find_node(4), 843 Some(Located::Expression { 844 expression: &string, 845 position: ExpressionPosition::Expression 846 }) 847 ); 848 assert_eq!( 849 access.find_node(9), 850 Some(Located::Expression { 851 expression: &string, 852 position: ExpressionPosition::Expression 853 }) 854 ); 855 assert_eq!( 856 access.find_node(12), 857 Some(Located::Expression { 858 expression: &int, 859 position: ExpressionPosition::Expression 860 }) 861 ); 862 assert_eq!( 863 access.find_node(15), 864 Some(Located::Expression { 865 expression: access, 866 position: ExpressionPosition::Expression 867 }) 868 ); 869 assert_eq!( 870 access.find_node(18), 871 Some(Located::Expression { 872 expression: access, 873 position: ExpressionPosition::Expression 874 }) 875 ); 876 assert_eq!( 877 access.find_node(19), 878 Some(Located::Expression { 879 expression: access, 880 position: ExpressionPosition::Expression 881 }) 882 ); 883} 884 885#[test] 886fn find_node_record_update() { 887 let statement = compile_expression(r#"Cat(..Cat("Nubi", 3), age: 4)"#); 888 let update = get_bare_expression(&statement); 889 890 let int = TypedExpr::Int { 891 location: SrcSpan { start: 27, end: 28 }, 892 value: "4".into(), 893 int_value: 4.into(), 894 type_: type_::int(), 895 }; 896 897 assert_eq!( 898 update.find_node(0), 899 Some(Located::Expression { 900 expression: update, 901 position: ExpressionPosition::Expression 902 }) 903 ); 904 assert_eq!( 905 update.find_node(3), 906 Some(Located::Expression { 907 expression: update, 908 position: ExpressionPosition::Expression 909 }) 910 ); 911 assert_eq!( 912 update.find_node(27), 913 Some(Located::Expression { 914 expression: &int, 915 position: ExpressionPosition::Expression 916 }) 917 ); 918 assert_eq!( 919 update.find_node(28), 920 Some(Located::Expression { 921 expression: &int, 922 position: ExpressionPosition::Expression 923 }) 924 ); 925 assert_eq!( 926 update.find_node(29), 927 Some(Located::Expression { 928 expression: update, 929 position: ExpressionPosition::Expression 930 }) 931 ); 932} 933 934#[test] 935fn find_node_case() { 936 let statement = compile_expression( 937 r#" 938case 1, 2 { 939 _, _ -> 3 940} 941"#, 942 ); 943 let case = get_bare_expression(&statement); 944 945 let int1 = TypedExpr::Int { 946 location: SrcSpan { start: 6, end: 7 }, 947 value: "1".into(), 948 int_value: 1.into(), 949 type_: type_::int(), 950 }; 951 952 let int2 = TypedExpr::Int { 953 location: SrcSpan { start: 9, end: 10 }, 954 value: "2".into(), 955 int_value: 2.into(), 956 type_: type_::int(), 957 }; 958 959 let int3 = TypedExpr::Int { 960 location: SrcSpan { start: 23, end: 24 }, 961 value: "3".into(), 962 int_value: 3.into(), 963 type_: type_::int(), 964 }; 965 966 assert_eq!( 967 case.find_node(1), 968 Some(Located::Expression { 969 expression: case, 970 position: ExpressionPosition::Expression 971 }) 972 ); 973 assert_eq!( 974 case.find_node(6), 975 Some(Located::Expression { 976 expression: &int1, 977 position: ExpressionPosition::Expression 978 }) 979 ); 980 assert_eq!( 981 case.find_node(9), 982 Some(Located::Expression { 983 expression: &int2, 984 position: ExpressionPosition::Expression 985 }) 986 ); 987 assert_eq!( 988 case.find_node(23), 989 Some(Located::Expression { 990 expression: &int3, 991 position: ExpressionPosition::Expression 992 }) 993 ); 994 assert_eq!( 995 case.find_node(25), 996 Some(Located::Expression { 997 expression: case, 998 position: ExpressionPosition::Expression 999 }) 1000 ); 1001 assert_eq!( 1002 case.find_node(26), 1003 Some(Located::Expression { 1004 expression: case, 1005 position: ExpressionPosition::Expression 1006 }) 1007 ); 1008 assert_eq!(case.find_node(27), None); 1009} 1010 1011#[test] 1012fn find_node_bool() { 1013 let statement = compile_expression(r#"!True"#); 1014 let negate = get_bare_expression(&statement); 1015 1016 let bool = TypedExpr::Var { 1017 location: SrcSpan { start: 1, end: 5 }, 1018 constructor: ValueConstructor { 1019 deprecation: Deprecation::NotDeprecated, 1020 publicity: Publicity::Public, 1021 variant: ValueConstructorVariant::Record { 1022 documentation: None, 1023 variants_count: 2, 1024 name: "True".into(), 1025 arity: 0, 1026 field_map: None, 1027 location: SrcSpan { start: 0, end: 0 }, 1028 module: PRELUDE_MODULE_NAME.into(), 1029 variant_index: 0, 1030 }, 1031 type_: type_::bool_with_variant(Some(true)), 1032 }, 1033 name: "True".into(), 1034 }; 1035 1036 assert_eq!( 1037 negate.find_node(0), 1038 Some(Located::Expression { 1039 expression: negate, 1040 position: ExpressionPosition::Expression 1041 }) 1042 ); 1043 assert_eq!( 1044 negate.find_node(1), 1045 Some(Located::Expression { 1046 expression: &bool, 1047 position: ExpressionPosition::Expression 1048 }) 1049 ); 1050 assert_eq!( 1051 negate.find_node(2), 1052 Some(Located::Expression { 1053 expression: &bool, 1054 position: ExpressionPosition::Expression 1055 }) 1056 ); 1057 assert_eq!( 1058 negate.find_node(3), 1059 Some(Located::Expression { 1060 expression: &bool, 1061 position: ExpressionPosition::Expression 1062 }) 1063 ); 1064 assert_eq!( 1065 negate.find_node(4), 1066 Some(Located::Expression { 1067 expression: &bool, 1068 position: ExpressionPosition::Expression 1069 }) 1070 ); 1071 assert_eq!( 1072 negate.find_node(5), 1073 Some(Located::Expression { 1074 expression: &bool, 1075 position: ExpressionPosition::Expression 1076 }) 1077 ); 1078} 1079 1080#[test] 1081fn find_node_statement_fn() { 1082 let module = compile_module( 1083 r#" 1084 1085pub fn main() { 1086 Nil 1087} 1088 1089"#, 1090 ); 1091 1092 assert!(module.find_node(0).is_none()); 1093 assert!(module.find_node(1).is_none()); 1094 1095 // The fn 1096 assert!(module.find_node(2).is_some()); 1097 assert!(module.find_node(24).is_some()); 1098 assert!(module.find_node(25).is_some()); 1099 assert!(module.find_node(26).is_none()); 1100} 1101 1102#[test] 1103fn find_node_statement_import() { 1104 let module = compile_module( 1105 r#" 1106import gleam 1107"#, 1108 ); 1109 1110 assert!(module.find_node(0).is_none()); 1111 1112 // The import 1113 assert!(module.find_node(1).is_some()); 1114 assert!(module.find_node(12).is_some()); 1115 assert!(module.find_node(13).is_some()); 1116 assert!(module.find_node(14).is_none()); 1117} 1118 1119#[test] 1120fn find_node_use() { 1121 let use_ = compile_expression( 1122 r#" 1123use x <- fn(f) { f(1) } 1124124 1125"#, 1126 ); 1127 1128 assert!(use_.find_node(0).is_none()); 1129 assert!(use_.find_node(1).is_some()); // The use 1130 assert!(use_.find_node(23).is_some()); 1131 assert!(use_.find_node(26).is_some()); // The int 1132}