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 / metadata / tests.rs
69 kB 2088 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2021 The Gleam contributors 3 4use hexpm::version::Version; 5use rand::Rng; 6use type_::{AccessorsMap, FieldMap, RecordAccessor}; 7 8use super::*; 9use crate::{ 10 analyse::Inferred, 11 ast::{ 12 BitArrayOption, BitArraySegment, CallArg, Constant, Publicity, SrcSpan, TypedConstant, 13 TypedConstantBitArraySegmentOption, 14 }, 15 build::Origin, 16 line_numbers::LineNumbers, 17 parse::LiteralFloatValue, 18 reference::{ModuleNameReference, Reference, ReferenceKind}, 19 type_::{ 20 self, Deprecation, ModuleInterface, Opaque, References, Type, TypeAliasConstructor, 21 TypeConstructor, TypeValueConstructor, TypeValueConstructorField, TypeVariantConstructors, 22 ValueConstructor, ValueConstructorVariant, 23 expression::{Implementations, Purity}, 24 prelude, 25 }, 26 uid::UniqueIdGenerator, 27}; 28use std::{collections::HashMap, sync::Arc}; 29 30use pretty_assertions::assert_eq; 31 32fn roundtrip(input: &ModuleInterface) -> ModuleInterface { 33 let buffer = encode(input).unwrap(); 34 let ids = UniqueIdGenerator::new(); 35 decode(buffer.as_slice(), ids).unwrap() 36} 37 38fn constant_module(constant: TypedConstant) -> ModuleInterface { 39 ModuleInterface { 40 warnings: vec![], 41 is_internal: true, 42 package: "some_package".into(), 43 origin: Origin::Src, 44 name: "a".into(), 45 types: HashMap::new(), 46 types_value_constructors: HashMap::new(), 47 accessors: HashMap::new(), 48 values: [( 49 "one".into(), 50 ValueConstructor { 51 publicity: Publicity::Public, 52 deprecation: Deprecation::NotDeprecated, 53 type_: type_::int(), 54 variant: ValueConstructorVariant::ModuleConstant { 55 documentation: Some("Some documentation".into()), 56 literal: constant, 57 location: SrcSpan::default(), 58 module: "one/two".into(), 59 implementations: Implementations { 60 gleam: true, 61 uses_erlang_externals: false, 62 uses_javascript_externals: false, 63 uses_cranelift_externals: false, 64 can_run_on_erlang: true, 65 can_run_on_javascript: true, 66 can_run_on_cranelift: true, 67 }, 68 name: "one".into(), 69 }, 70 }, 71 )] 72 .into(), 73 line_numbers: LineNumbers::new(""), 74 src_path: "some_path".into(), 75 minimum_required_version: Version::new(0, 1, 0), 76 type_aliases: HashMap::new(), 77 documentation: Vec::new(), 78 contains_echo: false, 79 80 references: References::default(), 81 inline_functions: HashMap::new(), 82 } 83} 84 85fn bit_array_segment_option_module(option: TypedConstantBitArraySegmentOption) -> ModuleInterface { 86 constant_module(Constant::BitArray { 87 location: SrcSpan::default(), 88 segments: vec![BitArraySegment { 89 location: SrcSpan::default(), 90 value: Box::new(Constant::Int { 91 location: SrcSpan::default(), 92 value: "1".into(), 93 int_value: 1.into(), 94 }), 95 options: vec![option], 96 type_: type_::int(), 97 }], 98 }) 99} 100 101#[test] 102fn empty_module() { 103 let module = ModuleInterface { 104 warnings: vec![], 105 is_internal: true, 106 package: "some_package".into(), 107 origin: Origin::Src, 108 name: "one/two".into(), 109 types: HashMap::new(), 110 types_value_constructors: HashMap::new(), 111 values: HashMap::new(), 112 accessors: HashMap::new(), 113 line_numbers: LineNumbers::new(""), 114 src_path: "some_path".into(), 115 minimum_required_version: Version::new(0, 1, 0), 116 type_aliases: HashMap::new(), 117 documentation: Vec::new(), 118 contains_echo: false, 119 120 references: References::default(), 121 inline_functions: HashMap::new(), 122 }; 123 assert_eq!(roundtrip(&module), module); 124} 125 126#[test] 127fn with_line_numbers() { 128 let module = ModuleInterface { 129 warnings: vec![], 130 is_internal: false, 131 package: "some_package".into(), 132 origin: Origin::Src, 133 name: "one/two".into(), 134 types: HashMap::new(), 135 types_value_constructors: HashMap::new(), 136 values: HashMap::new(), 137 accessors: HashMap::new(), 138 line_numbers: LineNumbers::new( 139 "const a = 1 140 const b = 2 141 const c = 3", 142 ), 143 src_path: "some_path".into(), 144 minimum_required_version: Version::new(0, 1, 0), 145 type_aliases: HashMap::new(), 146 documentation: Vec::new(), 147 contains_echo: false, 148 149 references: References::default(), 150 inline_functions: HashMap::new(), 151 }; 152 assert_eq!(roundtrip(&module), module); 153} 154 155#[test] 156fn module_with_private_type() { 157 let module = ModuleInterface { 158 warnings: vec![], 159 is_internal: false, 160 package: "some_package".into(), 161 origin: Origin::Src, 162 name: "a/b".into(), 163 types: [( 164 "ListIntType".into(), 165 TypeConstructor { 166 type_: type_::list(type_::int()), 167 publicity: Publicity::Private, 168 origin: SrcSpan::default(), 169 module: "the/module".into(), 170 parameters: vec![], 171 deprecation: Deprecation::NotDeprecated, 172 documentation: None, 173 }, 174 )] 175 .into(), 176 types_value_constructors: HashMap::new(), 177 values: HashMap::new(), 178 accessors: HashMap::new(), 179 line_numbers: LineNumbers::new(""), 180 src_path: "some_path".into(), 181 minimum_required_version: Version::new(0, 1, 0), 182 type_aliases: HashMap::new(), 183 documentation: Vec::new(), 184 contains_echo: false, 185 186 references: References::default(), 187 inline_functions: HashMap::new(), 188 }; 189 assert_eq!(roundtrip(&module), module); 190} 191 192#[test] 193fn module_with_app_type() { 194 let module = ModuleInterface { 195 warnings: vec![], 196 is_internal: false, 197 package: "some_package".into(), 198 origin: Origin::Src, 199 name: "a/b".into(), 200 types: [( 201 "ListIntType".into(), 202 TypeConstructor { 203 type_: type_::list(type_::int()), 204 publicity: Publicity::Public, 205 origin: SrcSpan::default(), 206 module: "the/module".into(), 207 parameters: vec![], 208 deprecation: Deprecation::NotDeprecated, 209 documentation: None, 210 }, 211 )] 212 .into(), 213 types_value_constructors: HashMap::new(), 214 values: HashMap::new(), 215 accessors: HashMap::new(), 216 line_numbers: LineNumbers::new(""), 217 src_path: "some_path".into(), 218 minimum_required_version: Version::new(0, 1, 0), 219 type_aliases: HashMap::new(), 220 documentation: Vec::new(), 221 contains_echo: false, 222 223 references: References::default(), 224 inline_functions: HashMap::new(), 225 }; 226 assert_eq!(roundtrip(&module), module); 227} 228 229#[test] 230fn module_with_fn_type() { 231 let module = ModuleInterface { 232 warnings: vec![], 233 is_internal: false, 234 package: "some_package".into(), 235 origin: Origin::Src, 236 name: "a/b".into(), 237 types: [( 238 "FnType".into(), 239 TypeConstructor { 240 type_: type_::fn_(vec![type_::nil(), type_::float()], type_::int()), 241 publicity: Publicity::Public, 242 origin: SrcSpan::default(), 243 module: "the/module".into(), 244 parameters: vec![], 245 deprecation: Deprecation::NotDeprecated, 246 documentation: None, 247 }, 248 )] 249 .into(), 250 types_value_constructors: HashMap::new(), 251 values: HashMap::new(), 252 accessors: HashMap::new(), 253 line_numbers: LineNumbers::new(""), 254 src_path: "some_path".into(), 255 minimum_required_version: Version::new(0, 1, 0), 256 type_aliases: HashMap::new(), 257 documentation: Vec::new(), 258 contains_echo: false, 259 260 references: References::default(), 261 inline_functions: HashMap::new(), 262 }; 263 assert_eq!(roundtrip(&module), module); 264} 265 266#[test] 267fn module_with_tuple_type() { 268 let module = ModuleInterface { 269 warnings: vec![], 270 is_internal: false, 271 package: "some_package".into(), 272 origin: Origin::Src, 273 name: "a/b".into(), 274 types: [( 275 "TupleType".into(), 276 TypeConstructor { 277 type_: type_::tuple(vec![type_::nil(), type_::float(), type_::int()]), 278 publicity: Publicity::Public, 279 origin: SrcSpan::default(), 280 module: "the/module".into(), 281 parameters: vec![], 282 deprecation: Deprecation::NotDeprecated, 283 documentation: None, 284 }, 285 )] 286 .into(), 287 types_value_constructors: HashMap::new(), 288 values: HashMap::new(), 289 accessors: HashMap::new(), 290 line_numbers: LineNumbers::new(""), 291 src_path: "some_path".into(), 292 minimum_required_version: Version::new(0, 1, 0), 293 type_aliases: HashMap::new(), 294 documentation: Vec::new(), 295 contains_echo: false, 296 297 references: References::default(), 298 inline_functions: HashMap::new(), 299 }; 300 assert_eq!(roundtrip(&module), module); 301} 302 303#[test] 304fn module_with_generic_type() { 305 let t0 = type_::generic_var(0); 306 let t1 = type_::generic_var(1); 307 let t7 = type_::generic_var(7); 308 let t8 = type_::generic_var(8); 309 310 fn make(t1: Arc<Type>, t2: Arc<Type>) -> ModuleInterface { 311 ModuleInterface { 312 warnings: vec![], 313 is_internal: false, 314 package: "some_package".into(), 315 origin: Origin::Src, 316 name: "a/b".into(), 317 types: [( 318 "TupleType".into(), 319 TypeConstructor { 320 type_: type_::tuple(vec![t1.clone(), t1.clone(), t2.clone()]), 321 publicity: Publicity::Public, 322 origin: SrcSpan::default(), 323 module: "the/module".into(), 324 parameters: vec![t1, t2], 325 deprecation: Deprecation::NotDeprecated, 326 documentation: None, 327 }, 328 )] 329 .into(), 330 types_value_constructors: HashMap::new(), 331 values: HashMap::new(), 332 accessors: HashMap::new(), 333 line_numbers: LineNumbers::new(""), 334 src_path: "some_path".into(), 335 minimum_required_version: Version::new(0, 1, 0), 336 type_aliases: HashMap::new(), 337 documentation: Vec::new(), 338 contains_echo: false, 339 references: References::default(), 340 inline_functions: HashMap::new(), 341 } 342 } 343 344 assert_eq!(roundtrip(&make(t7, t8)), make(t0, t1)); 345} 346 347#[test] 348fn module_with_type_links() { 349 let linked_type = type_::link(type_::int()); 350 let type_ = type_::int(); 351 352 fn make(type_: Arc<Type>) -> ModuleInterface { 353 ModuleInterface { 354 warnings: vec![], 355 is_internal: false, 356 package: "some_package".into(), 357 origin: Origin::Src, 358 name: "a".into(), 359 types: [( 360 "SomeType".into(), 361 TypeConstructor { 362 type_, 363 publicity: Publicity::Public, 364 origin: SrcSpan::default(), 365 module: "a".into(), 366 parameters: vec![], 367 deprecation: Deprecation::NotDeprecated, 368 documentation: None, 369 }, 370 )] 371 .into(), 372 types_value_constructors: HashMap::new(), 373 values: HashMap::new(), 374 accessors: HashMap::new(), 375 line_numbers: LineNumbers::new(""), 376 src_path: "some_path".into(), 377 minimum_required_version: Version::new(0, 1, 0), 378 type_aliases: HashMap::new(), 379 documentation: Vec::new(), 380 contains_echo: false, 381 references: References::default(), 382 inline_functions: HashMap::new(), 383 } 384 } 385 386 assert_eq!(roundtrip(&make(linked_type)), make(type_)); 387} 388 389#[test] 390fn module_with_type_constructor_documentation() { 391 let linked_type = type_::link(type_::int()); 392 let type_ = type_::int(); 393 394 fn make(type_: Arc<Type>) -> ModuleInterface { 395 ModuleInterface { 396 warnings: vec![], 397 is_internal: false, 398 package: "some_package".into(), 399 origin: Origin::Src, 400 name: "a".into(), 401 types: [( 402 "SomeType".into(), 403 TypeConstructor { 404 type_, 405 publicity: Publicity::Public, 406 origin: SrcSpan::default(), 407 module: "a".into(), 408 parameters: vec![], 409 deprecation: Deprecation::NotDeprecated, 410 documentation: Some("type documentation".into()), 411 }, 412 )] 413 .into(), 414 types_value_constructors: HashMap::new(), 415 values: HashMap::new(), 416 accessors: HashMap::new(), 417 line_numbers: LineNumbers::new(""), 418 src_path: "some_path".into(), 419 minimum_required_version: Version::new(0, 1, 0), 420 type_aliases: HashMap::new(), 421 documentation: Vec::new(), 422 contains_echo: false, 423 references: References::default(), 424 inline_functions: HashMap::new(), 425 } 426 } 427 428 assert_eq!(roundtrip(&make(linked_type)), make(type_)); 429} 430 431#[test] 432fn module_with_type_constructor_origin() { 433 let linked_type = type_::link(type_::int()); 434 let type_ = type_::int(); 435 436 fn make(type_: Arc<Type>) -> ModuleInterface { 437 ModuleInterface { 438 warnings: vec![], 439 is_internal: false, 440 package: "some_package".into(), 441 origin: Origin::Src, 442 name: "a".into(), 443 types: [( 444 "SomeType".into(), 445 TypeConstructor { 446 type_, 447 publicity: Publicity::Public, 448 origin: SrcSpan { 449 start: 535, 450 end: 543, 451 }, 452 module: "a".into(), 453 parameters: vec![], 454 deprecation: Deprecation::NotDeprecated, 455 documentation: None, 456 }, 457 )] 458 .into(), 459 types_value_constructors: HashMap::new(), 460 values: HashMap::new(), 461 accessors: HashMap::new(), 462 line_numbers: LineNumbers::new(""), 463 src_path: "some_path".into(), 464 minimum_required_version: Version::new(0, 1, 0), 465 type_aliases: HashMap::new(), 466 documentation: Vec::new(), 467 contains_echo: false, 468 references: References::default(), 469 inline_functions: HashMap::new(), 470 } 471 } 472 473 assert_eq!(roundtrip(&make(linked_type)), make(type_)); 474} 475 476#[test] 477fn module_type_to_constructors_mapping() { 478 let module = ModuleInterface { 479 warnings: vec![], 480 is_internal: false, 481 package: "some_package".into(), 482 origin: Origin::Src, 483 name: "a".into(), 484 types: HashMap::new(), 485 types_value_constructors: [( 486 "SomeType".into(), 487 TypeVariantConstructors { 488 type_parameters_ids: vec![0, 1, 2], 489 variants: vec![TypeValueConstructor { 490 name: "One".into(), 491 parameters: vec![], 492 documentation: Some("Some documentation".into()), 493 }], 494 opaque: Opaque::NotOpaque, 495 }, 496 )] 497 .into(), 498 accessors: HashMap::new(), 499 values: HashMap::new(), 500 line_numbers: LineNumbers::new(""), 501 src_path: "some_path".into(), 502 minimum_required_version: Version::new(0, 1, 0), 503 type_aliases: HashMap::new(), 504 documentation: Vec::new(), 505 contains_echo: false, 506 507 references: References::default(), 508 inline_functions: HashMap::new(), 509 }; 510 511 assert_eq!(roundtrip(&module), module); 512} 513 514#[test] 515fn module_fn_value() { 516 let module = ModuleInterface { 517 warnings: vec![], 518 is_internal: false, 519 package: "some_package".into(), 520 origin: Origin::Src, 521 name: "a".into(), 522 types: HashMap::new(), 523 types_value_constructors: HashMap::new(), 524 accessors: HashMap::new(), 525 values: [( 526 "one".into(), 527 ValueConstructor { 528 publicity: Publicity::Public, 529 deprecation: Deprecation::NotDeprecated, 530 type_: type_::int(), 531 variant: ValueConstructorVariant::ModuleFn { 532 documentation: Some("wobble!".into()), 533 name: "one".into(), 534 field_map: None, 535 module: "a".into(), 536 arity: 5, 537 location: SrcSpan { 538 start: 535, 539 end: 1100, 540 }, 541 external_erlang: None, 542 external_javascript: None, 543 external_cranelift: None, 544 implementations: Implementations { 545 gleam: true, 546 uses_erlang_externals: false, 547 uses_javascript_externals: false, 548 uses_cranelift_externals: false, 549 can_run_on_erlang: true, 550 can_run_on_javascript: true, 551 can_run_on_cranelift: true, 552 }, 553 purity: Purity::Pure, 554 }, 555 }, 556 )] 557 .into(), 558 line_numbers: LineNumbers::new(""), 559 src_path: "some_path".into(), 560 minimum_required_version: Version::new(0, 1, 0), 561 type_aliases: HashMap::new(), 562 documentation: Vec::new(), 563 contains_echo: false, 564 565 references: References::default(), 566 inline_functions: HashMap::new(), 567 }; 568 assert_eq!(roundtrip(&module), module); 569} 570 571#[test] 572fn deprecated_module_fn_value() { 573 let module = ModuleInterface { 574 warnings: vec![], 575 is_internal: false, 576 package: "some_package".into(), 577 origin: Origin::Src, 578 name: "a".into(), 579 types: HashMap::new(), 580 types_value_constructors: HashMap::new(), 581 accessors: HashMap::new(), 582 values: [( 583 "one".into(), 584 ValueConstructor { 585 publicity: Publicity::Public, 586 deprecation: Deprecation::Deprecated { 587 message: "wibble wobble".into(), 588 }, 589 type_: type_::int(), 590 variant: ValueConstructorVariant::ModuleFn { 591 documentation: Some("wobble!".into()), 592 name: "one".into(), 593 field_map: None, 594 module: "a".into(), 595 arity: 5, 596 location: SrcSpan { 597 start: 535, 598 end: 1100, 599 }, 600 external_erlang: None, 601 external_javascript: None, 602 external_cranelift: None, 603 implementations: Implementations { 604 gleam: true, 605 uses_erlang_externals: false, 606 uses_javascript_externals: false, 607 uses_cranelift_externals: false, 608 can_run_on_erlang: true, 609 can_run_on_javascript: true, 610 can_run_on_cranelift: true, 611 }, 612 purity: Purity::Pure, 613 }, 614 }, 615 )] 616 .into(), 617 line_numbers: LineNumbers::new(""), 618 src_path: "some_path".into(), 619 minimum_required_version: Version::new(0, 1, 0), 620 type_aliases: HashMap::new(), 621 documentation: Vec::new(), 622 contains_echo: false, 623 624 references: References::default(), 625 inline_functions: HashMap::new(), 626 }; 627 assert_eq!(roundtrip(&module), module); 628} 629 630#[test] 631fn private_module_fn_value() { 632 let module = ModuleInterface { 633 warnings: vec![], 634 is_internal: false, 635 package: "some_package".into(), 636 origin: Origin::Src, 637 name: "a".into(), 638 types: HashMap::new(), 639 types_value_constructors: HashMap::new(), 640 accessors: HashMap::new(), 641 values: [( 642 "one".into(), 643 ValueConstructor { 644 publicity: Publicity::Private, 645 deprecation: Deprecation::NotDeprecated, 646 type_: type_::int(), 647 variant: ValueConstructorVariant::ModuleFn { 648 documentation: Some("wobble!".into()), 649 name: "one".into(), 650 field_map: None, 651 module: "a".into(), 652 arity: 5, 653 location: SrcSpan { 654 start: 535, 655 end: 1100, 656 }, 657 external_erlang: None, 658 external_javascript: None, 659 external_cranelift: None, 660 implementations: Implementations { 661 gleam: true, 662 uses_erlang_externals: false, 663 uses_javascript_externals: false, 664 uses_cranelift_externals: false, 665 can_run_on_erlang: true, 666 can_run_on_javascript: true, 667 can_run_on_cranelift: true, 668 }, 669 purity: Purity::Pure, 670 }, 671 }, 672 )] 673 .into(), 674 line_numbers: LineNumbers::new(""), 675 src_path: "some_path".into(), 676 minimum_required_version: Version::new(0, 1, 0), 677 type_aliases: HashMap::new(), 678 documentation: Vec::new(), 679 contains_echo: false, 680 681 references: References::default(), 682 inline_functions: HashMap::new(), 683 }; 684 685 assert_eq!(roundtrip(&module), module); 686} 687 688// https://github.com/gleam-lang/gleam/commit/c8f3bd0ddbf61c27ea35f37297058ecca7515f6c 689#[test] 690fn module_fn_value_regression() { 691 let module = ModuleInterface { 692 warnings: vec![], 693 is_internal: false, 694 package: "some_package".into(), 695 origin: Origin::Src, 696 name: "a/b/c".into(), 697 types: HashMap::new(), 698 types_value_constructors: HashMap::new(), 699 accessors: HashMap::new(), 700 values: [( 701 "one".into(), 702 ValueConstructor { 703 publicity: Publicity::Public, 704 deprecation: Deprecation::NotDeprecated, 705 type_: type_::int(), 706 variant: ValueConstructorVariant::ModuleFn { 707 documentation: Some("wabble!".into()), 708 name: "one".into(), 709 field_map: None, 710 module: "a".into(), 711 arity: 5, 712 location: SrcSpan { 713 start: 52, 714 end: 1100, 715 }, 716 external_erlang: None, 717 external_javascript: None, 718 external_cranelift: None, 719 implementations: Implementations { 720 gleam: true, 721 uses_erlang_externals: false, 722 uses_javascript_externals: false, 723 uses_cranelift_externals: false, 724 can_run_on_erlang: true, 725 can_run_on_javascript: true, 726 can_run_on_cranelift: true, 727 }, 728 purity: Purity::TrustedPure, 729 }, 730 }, 731 )] 732 .into(), 733 line_numbers: LineNumbers::new(""), 734 src_path: "some_path".into(), 735 minimum_required_version: Version::new(0, 1, 0), 736 type_aliases: HashMap::new(), 737 documentation: Vec::new(), 738 contains_echo: false, 739 740 references: References::default(), 741 inline_functions: HashMap::new(), 742 }; 743 744 assert_eq!(roundtrip(&module), module); 745} 746 747#[test] 748fn module_fn_value_with_field_map() { 749 let module = ModuleInterface { 750 warnings: vec![], 751 is_internal: false, 752 package: "some_package".into(), 753 origin: Origin::Src, 754 name: "a".into(), 755 types: HashMap::new(), 756 types_value_constructors: HashMap::new(), 757 accessors: HashMap::new(), 758 values: [( 759 "one".into(), 760 ValueConstructor { 761 publicity: Publicity::Public, 762 deprecation: Deprecation::NotDeprecated, 763 type_: type_::int(), 764 variant: ValueConstructorVariant::ModuleFn { 765 documentation: Some("wubble!".into()), 766 name: "one".into(), 767 field_map: Some(FieldMap { 768 arity: 20, 769 fields: [("ok".into(), 5), ("ko".into(), 7)].into(), 770 }), 771 external_erlang: None, 772 external_javascript: None, 773 external_cranelift: None, 774 module: "a".into(), 775 arity: 5, 776 location: SrcSpan { start: 2, end: 11 }, 777 implementations: Implementations { 778 gleam: true, 779 uses_erlang_externals: false, 780 uses_javascript_externals: false, 781 uses_cranelift_externals: false, 782 can_run_on_erlang: true, 783 can_run_on_javascript: true, 784 can_run_on_cranelift: true, 785 }, 786 purity: Purity::Pure, 787 }, 788 }, 789 )] 790 .into(), 791 line_numbers: LineNumbers::new(""), 792 src_path: "some_path".into(), 793 minimum_required_version: Version::new(0, 1, 0), 794 type_aliases: HashMap::new(), 795 documentation: Vec::new(), 796 contains_echo: false, 797 798 references: References::default(), 799 inline_functions: HashMap::new(), 800 }; 801 802 assert_eq!(roundtrip(&module), module); 803} 804 805#[test] 806fn record_value() { 807 let mut random = rand::rng(); 808 809 let module = ModuleInterface { 810 warnings: vec![], 811 is_internal: false, 812 package: "some_package".into(), 813 origin: Origin::Src, 814 name: "a".into(), 815 types: HashMap::new(), 816 types_value_constructors: HashMap::new(), 817 accessors: HashMap::new(), 818 values: [( 819 "one".into(), 820 ValueConstructor { 821 publicity: Publicity::Public, 822 deprecation: Deprecation::NotDeprecated, 823 type_: type_::int(), 824 variant: ValueConstructorVariant::Record { 825 documentation: Some("webble!".into()), 826 name: "one".into(), 827 module: "themodule".into(), 828 field_map: None, 829 arity: random.random(), 830 variants_count: random.random(), 831 location: SrcSpan { 832 start: random.random(), 833 end: random.random(), 834 }, 835 variant_index: random.random(), 836 }, 837 }, 838 )] 839 .into(), 840 line_numbers: LineNumbers::new(""), 841 src_path: "some_path".into(), 842 minimum_required_version: Version::new(0, 1, 0), 843 type_aliases: HashMap::new(), 844 documentation: Vec::new(), 845 contains_echo: false, 846 847 references: References::default(), 848 inline_functions: HashMap::new(), 849 }; 850 851 assert_eq!(roundtrip(&module), module); 852} 853 854#[test] 855fn record_value_with_field_map() { 856 let mut random = rand::rng(); 857 858 let module = ModuleInterface { 859 warnings: vec![], 860 is_internal: false, 861 package: "some_package".into(), 862 origin: Origin::Src, 863 name: "a".into(), 864 types: HashMap::new(), 865 types_value_constructors: HashMap::new(), 866 accessors: HashMap::new(), 867 values: [( 868 "one".into(), 869 ValueConstructor { 870 publicity: Publicity::Public, 871 deprecation: Deprecation::NotDeprecated, 872 type_: type_::int(), 873 variant: ValueConstructorVariant::Record { 874 documentation: Some("wybble!".into()), 875 module: "themodule".into(), 876 name: "one".into(), 877 field_map: Some(FieldMap { 878 arity: random.random(), 879 fields: [ 880 ("ok".into(), random.random()), 881 ("ko".into(), random.random()), 882 ] 883 .into(), 884 }), 885 arity: random.random(), 886 variants_count: random.random(), 887 variant_index: random.random(), 888 location: SrcSpan { 889 start: random.random(), 890 end: random.random(), 891 }, 892 }, 893 }, 894 )] 895 .into(), 896 line_numbers: LineNumbers::new(""), 897 src_path: "some_path".into(), 898 minimum_required_version: Version::new(0, 1, 0), 899 type_aliases: HashMap::new(), 900 documentation: Vec::new(), 901 contains_echo: false, 902 903 references: References::default(), 904 inline_functions: HashMap::new(), 905 }; 906 907 assert_eq!(roundtrip(&module), module); 908} 909 910#[test] 911fn accessors() { 912 let accessors1 = [ 913 ( 914 "a".into(), 915 RecordAccessor { 916 index: 6, 917 label: "siiixxx".into(), 918 type_: type_::nil(), 919 documentation: Some("Here is some documentation".into()), 920 }, 921 ), 922 ( 923 "a".into(), 924 RecordAccessor { 925 index: 5, 926 label: "fiveee".into(), 927 type_: type_::float(), 928 documentation: None, 929 }, 930 ), 931 ]; 932 933 let accessors2 = [( 934 "a".into(), 935 RecordAccessor { 936 index: 1, 937 label: "ok".into(), 938 type_: type_::float(), 939 documentation: Some("Documentation for the ok field".into()), 940 }, 941 )]; 942 943 let module = ModuleInterface { 944 warnings: vec![], 945 is_internal: false, 946 package: "some_package".into(), 947 origin: Origin::Src, 948 name: "a".into(), 949 types: HashMap::new(), 950 types_value_constructors: HashMap::new(), 951 values: HashMap::new(), 952 accessors: [ 953 ( 954 "one".into(), 955 AccessorsMap { 956 publicity: Publicity::Public, 957 type_: type_::int(), 958 shared_accessors: accessors1.clone().into(), 959 variant_specific_accessors: vec![accessors1.into()], 960 variant_positional_accessors: vec![vec![type_::int(), type_::float()]], 961 }, 962 ), 963 ( 964 "two".into(), 965 AccessorsMap { 966 publicity: Publicity::Public, 967 type_: type_::int(), 968 shared_accessors: accessors2.clone().into(), 969 variant_specific_accessors: vec![accessors2.into()], 970 variant_positional_accessors: vec![vec![]], 971 }, 972 ), 973 ] 974 .into(), 975 line_numbers: LineNumbers::new(""), 976 src_path: "some_path".into(), 977 minimum_required_version: Version::new(0, 1, 0), 978 type_aliases: HashMap::new(), 979 documentation: Vec::new(), 980 contains_echo: false, 981 982 references: References::default(), 983 inline_functions: HashMap::new(), 984 }; 985 986 assert_eq!(roundtrip(&module), module); 987} 988 989#[test] 990fn private_accessors() { 991 let accessors1 = [ 992 ( 993 "a".into(), 994 RecordAccessor { 995 index: 6, 996 label: "siiixxx".into(), 997 type_: type_::nil(), 998 documentation: None, 999 }, 1000 ), 1001 ( 1002 "a".into(), 1003 RecordAccessor { 1004 index: 5, 1005 label: "fiveee".into(), 1006 type_: type_::float(), 1007 documentation: None, 1008 }, 1009 ), 1010 ]; 1011 1012 let accessors2 = [( 1013 "a".into(), 1014 RecordAccessor { 1015 index: 1, 1016 label: "ok".into(), 1017 type_: type_::float(), 1018 documentation: None, 1019 }, 1020 )]; 1021 1022 let module = ModuleInterface { 1023 warnings: vec![], 1024 is_internal: false, 1025 package: "some_package".into(), 1026 origin: Origin::Src, 1027 name: "a".into(), 1028 types: HashMap::new(), 1029 types_value_constructors: HashMap::new(), 1030 contains_echo: false, 1031 values: HashMap::new(), 1032 accessors: [ 1033 ( 1034 "one".into(), 1035 AccessorsMap { 1036 publicity: Publicity::Private, 1037 type_: type_::int(), 1038 shared_accessors: accessors1.clone().into(), 1039 variant_specific_accessors: vec![accessors1.into()], 1040 variant_positional_accessors: vec![vec![type_::int(), type_::float()]], 1041 }, 1042 ), 1043 ( 1044 "two".into(), 1045 AccessorsMap { 1046 publicity: Publicity::Public, 1047 type_: type_::int(), 1048 shared_accessors: accessors2.clone().into(), 1049 variant_specific_accessors: vec![accessors2.into()], 1050 variant_positional_accessors: vec![vec![]], 1051 }, 1052 ), 1053 ] 1054 .into(), 1055 line_numbers: LineNumbers::new(""), 1056 src_path: "some_path".into(), 1057 minimum_required_version: Version::new(0, 1, 0), 1058 type_aliases: HashMap::new(), 1059 documentation: Vec::new(), 1060 references: References::default(), 1061 inline_functions: HashMap::new(), 1062 }; 1063 1064 assert_eq!(roundtrip(&module), module); 1065} 1066 1067#[test] 1068fn constant_int() { 1069 let module = constant_module(Constant::Int { 1070 location: SrcSpan::default(), 1071 value: "100".into(), 1072 int_value: 100.into(), 1073 }); 1074 1075 assert_eq!(roundtrip(&module), module); 1076} 1077 1078#[test] 1079fn constant_float() { 1080 let module = constant_module(Constant::Float { 1081 location: SrcSpan::default(), 1082 value: "1.0".into(), 1083 float_value: LiteralFloatValue::ONE, 1084 }); 1085 1086 assert_eq!(roundtrip(&module), module); 1087} 1088 1089#[test] 1090fn constant_string() { 1091 let module = constant_module(Constant::String { 1092 location: SrcSpan::default(), 1093 value: "hello".into(), 1094 }); 1095 1096 assert_eq!(roundtrip(&module), module); 1097} 1098 1099#[test] 1100fn constant_tuple() { 1101 let int_float_tuple_type = type_::tuple(vec![type_::int(), type_::float()]); 1102 let module = constant_module(Constant::Tuple { 1103 location: SrcSpan::default(), 1104 type_: type_::tuple(vec![ 1105 type_::int(), 1106 type_::float(), 1107 int_float_tuple_type.clone(), 1108 ]), 1109 elements: vec![ 1110 Constant::Int { 1111 location: SrcSpan::default(), 1112 value: "1".into(), 1113 int_value: 1.into(), 1114 }, 1115 Constant::Float { 1116 location: SrcSpan::default(), 1117 value: "1.0".into(), 1118 float_value: LiteralFloatValue::ONE, 1119 }, 1120 Constant::Tuple { 1121 location: SrcSpan::default(), 1122 type_: int_float_tuple_type, 1123 elements: vec![ 1124 Constant::Int { 1125 location: SrcSpan::default(), 1126 value: "1".into(), 1127 int_value: 1.into(), 1128 }, 1129 Constant::Float { 1130 location: SrcSpan::default(), 1131 value: "1.0".into(), 1132 float_value: LiteralFloatValue::ONE, 1133 }, 1134 ], 1135 }, 1136 ], 1137 }); 1138 1139 assert_eq!(roundtrip(&module), module); 1140} 1141 1142#[test] 1143fn constant_list() { 1144 let module = constant_module(Constant::List { 1145 location: SrcSpan::default(), 1146 type_: type_::int(), 1147 elements: vec![ 1148 Constant::Int { 1149 location: SrcSpan::default(), 1150 value: "1".into(), 1151 int_value: 1.into(), 1152 }, 1153 Constant::Int { 1154 location: SrcSpan::default(), 1155 value: "2".into(), 1156 int_value: 2.into(), 1157 }, 1158 Constant::Int { 1159 location: SrcSpan::default(), 1160 value: "3".into(), 1161 int_value: 3.into(), 1162 }, 1163 ], 1164 tail: Some(Box::new(Constant::List { 1165 location: SrcSpan::default(), 1166 type_: type_::list(type_::int()), 1167 elements: vec![ 1168 Constant::Int { 1169 location: SrcSpan::default(), 1170 value: "4".into(), 1171 int_value: 4.into(), 1172 }, 1173 Constant::Int { 1174 location: SrcSpan::default(), 1175 value: "5".into(), 1176 int_value: 5.into(), 1177 }, 1178 ], 1179 tail: None, 1180 })), 1181 }); 1182 1183 assert_eq!(roundtrip(&module), module); 1184} 1185 1186#[test] 1187fn constant_record() { 1188 let module = constant_module(Constant::Record { 1189 location: SrcSpan::default(), 1190 module: None, 1191 name: "".into(), 1192 arguments: Some(vec![ 1193 CallArg { 1194 implicit: None, 1195 label: None, 1196 location: SrcSpan::default(), 1197 value: Constant::Float { 1198 location: SrcSpan::default(), 1199 value: "0.0".into(), 1200 float_value: LiteralFloatValue::ZERO, 1201 }, 1202 }, 1203 CallArg { 1204 implicit: None, 1205 label: None, 1206 location: SrcSpan::default(), 1207 value: Constant::Int { 1208 location: SrcSpan::default(), 1209 value: "1".into(), 1210 int_value: 1.into(), 1211 }, 1212 }, 1213 ]), 1214 type_: type_::int(), 1215 field_map: Inferred::Unknown, 1216 record_constructor: None, 1217 }); 1218 1219 assert_eq!(roundtrip(&module), module); 1220} 1221 1222#[test] 1223fn constant_var() { 1224 let one_original = Constant::Int { 1225 location: SrcSpan::default(), 1226 value: "1".into(), 1227 int_value: 1.into(), 1228 }; 1229 1230 let one = Constant::Var { 1231 location: SrcSpan::default(), 1232 module: None, 1233 name: "one_original".into(), 1234 type_: type_::int(), 1235 constructor: Some(Box::from(ValueConstructor { 1236 publicity: Publicity::Public, 1237 deprecation: Deprecation::NotDeprecated, 1238 type_: type_::int(), 1239 variant: ValueConstructorVariant::ModuleConstant { 1240 documentation: Some("some doc".into()), 1241 literal: one_original.clone(), 1242 location: SrcSpan::default(), 1243 module: "one/two".into(), 1244 implementations: Implementations { 1245 gleam: true, 1246 uses_erlang_externals: false, 1247 uses_javascript_externals: false, 1248 uses_cranelift_externals: false, 1249 can_run_on_erlang: true, 1250 can_run_on_javascript: true, 1251 can_run_on_cranelift: true, 1252 }, 1253 name: "one_original".into(), 1254 }, 1255 })), 1256 }; 1257 1258 let module = ModuleInterface { 1259 warnings: vec![], 1260 is_internal: false, 1261 package: "some_package".into(), 1262 origin: Origin::Src, 1263 name: "a".into(), 1264 types: HashMap::new(), 1265 types_value_constructors: HashMap::new(), 1266 accessors: HashMap::new(), 1267 values: [ 1268 ( 1269 "one".into(), 1270 ValueConstructor { 1271 publicity: Publicity::Public, 1272 deprecation: Deprecation::NotDeprecated, 1273 type_: type_::int(), 1274 variant: ValueConstructorVariant::ModuleConstant { 1275 documentation: Some("some doc!!!!!!!!!".into()), 1276 literal: one, 1277 location: SrcSpan::default(), 1278 module: "one/two".into(), 1279 implementations: Implementations { 1280 gleam: true, 1281 uses_erlang_externals: false, 1282 uses_javascript_externals: false, 1283 uses_cranelift_externals: false, 1284 can_run_on_erlang: true, 1285 can_run_on_javascript: true, 1286 can_run_on_cranelift: true, 1287 }, 1288 name: "one".into(), 1289 }, 1290 }, 1291 ), 1292 ( 1293 "one_original".into(), 1294 ValueConstructor { 1295 publicity: Publicity::Public, 1296 deprecation: Deprecation::NotDeprecated, 1297 type_: type_::int(), 1298 variant: ValueConstructorVariant::ModuleConstant { 1299 documentation: Some("some doc yeah".into()), 1300 literal: one_original, 1301 location: SrcSpan::default(), 1302 module: "one/two".into(), 1303 implementations: Implementations { 1304 gleam: true, 1305 uses_erlang_externals: false, 1306 uses_javascript_externals: false, 1307 uses_cranelift_externals: false, 1308 can_run_on_erlang: true, 1309 can_run_on_javascript: true, 1310 can_run_on_cranelift: true, 1311 }, 1312 name: "one_original".into(), 1313 }, 1314 }, 1315 ), 1316 ] 1317 .into(), 1318 line_numbers: LineNumbers::new(""), 1319 src_path: "some_path".into(), 1320 minimum_required_version: Version::new(0, 1, 0), 1321 type_aliases: HashMap::new(), 1322 documentation: Vec::new(), 1323 contains_echo: false, 1324 1325 references: References::default(), 1326 inline_functions: HashMap::new(), 1327 }; 1328 1329 assert_eq!(roundtrip(&module), module); 1330} 1331 1332#[test] 1333fn constant_bit_array() { 1334 let module = constant_module(Constant::BitArray { 1335 location: SrcSpan::default(), 1336 segments: vec![], 1337 }); 1338 assert_eq!(roundtrip(&module), module); 1339} 1340 1341#[test] 1342fn constant_bit_array_unit() { 1343 let module = bit_array_segment_option_module(BitArrayOption::Unit { 1344 location: SrcSpan::default(), 1345 value: 234, 1346 }); 1347 assert_eq!(roundtrip(&module), module); 1348} 1349 1350#[test] 1351fn constant_bit_array_float() { 1352 let module = bit_array_segment_option_module(BitArrayOption::Float { 1353 location: SrcSpan::default(), 1354 }); 1355 assert_eq!(roundtrip(&module), module); 1356} 1357 1358#[test] 1359fn constant_bit_array_int() { 1360 let module = bit_array_segment_option_module(BitArrayOption::Int { 1361 location: SrcSpan::default(), 1362 }); 1363 assert_eq!(roundtrip(&module), module); 1364} 1365 1366#[test] 1367fn constant_bit_array_size() { 1368 let module = bit_array_segment_option_module(BitArrayOption::Size { 1369 location: SrcSpan::default(), 1370 value: Box::new(Constant::Int { 1371 location: SrcSpan::default(), 1372 value: "1".into(), 1373 int_value: 1.into(), 1374 }), 1375 short_form: false, 1376 }); 1377 assert_eq!(roundtrip(&module), module); 1378} 1379 1380#[test] 1381fn constant_bit_array_size_short_form() { 1382 let module = bit_array_segment_option_module(BitArrayOption::Size { 1383 location: SrcSpan::default(), 1384 value: Box::new(Constant::Int { 1385 location: SrcSpan::default(), 1386 value: "1".into(), 1387 int_value: 1.into(), 1388 }), 1389 short_form: true, 1390 }); 1391 assert_eq!(roundtrip(&module), module); 1392} 1393 1394#[test] 1395fn constant_bit_array_bit_arry() { 1396 let module = bit_array_segment_option_module(BitArrayOption::Bits { 1397 location: SrcSpan::default(), 1398 }); 1399 assert_eq!(roundtrip(&module), module); 1400} 1401 1402#[test] 1403fn constant_bit_array_utf8() { 1404 let module = bit_array_segment_option_module(BitArrayOption::Utf8 { 1405 location: SrcSpan::default(), 1406 }); 1407 assert_eq!(roundtrip(&module), module); 1408} 1409 1410#[test] 1411fn constant_bit_array_utf16() { 1412 let module = bit_array_segment_option_module(BitArrayOption::Utf16 { 1413 location: SrcSpan::default(), 1414 }); 1415 assert_eq!(roundtrip(&module), module); 1416} 1417 1418#[test] 1419fn constant_bit_array_utf32() { 1420 let module = bit_array_segment_option_module(BitArrayOption::Utf32 { 1421 location: SrcSpan::default(), 1422 }); 1423 assert_eq!(roundtrip(&module), module); 1424} 1425 1426#[test] 1427fn constant_bit_array_utf8codepoint() { 1428 let module = bit_array_segment_option_module(BitArrayOption::Utf8Codepoint { 1429 location: SrcSpan::default(), 1430 }); 1431 assert_eq!(roundtrip(&module), module); 1432} 1433 1434#[test] 1435fn constant_bit_array_utf16codepoint() { 1436 let module = bit_array_segment_option_module(BitArrayOption::Utf16Codepoint { 1437 location: SrcSpan::default(), 1438 }); 1439 assert_eq!(roundtrip(&module), module); 1440} 1441 1442#[test] 1443fn constant_bit_array_utf32codepoint() { 1444 let module = bit_array_segment_option_module(BitArrayOption::Utf32Codepoint { 1445 location: SrcSpan::default(), 1446 }); 1447 assert_eq!(roundtrip(&module), module); 1448} 1449 1450#[test] 1451fn constant_bit_array_signed() { 1452 let module = bit_array_segment_option_module(BitArrayOption::Signed { 1453 location: SrcSpan::default(), 1454 }); 1455 assert_eq!(roundtrip(&module), module); 1456} 1457 1458#[test] 1459fn constant_bit_array_unsigned() { 1460 let module = bit_array_segment_option_module(BitArrayOption::Unsigned { 1461 location: SrcSpan::default(), 1462 }); 1463 assert_eq!(roundtrip(&module), module); 1464} 1465 1466#[test] 1467fn constant_bit_array_big() { 1468 let module = bit_array_segment_option_module(BitArrayOption::Big { 1469 location: SrcSpan::default(), 1470 }); 1471 assert_eq!(roundtrip(&module), module); 1472} 1473 1474#[test] 1475fn constant_bit_array_little() { 1476 let module = bit_array_segment_option_module(BitArrayOption::Little { 1477 location: SrcSpan::default(), 1478 }); 1479 assert_eq!(roundtrip(&module), module); 1480} 1481 1482#[test] 1483fn constant_bit_array_native() { 1484 let module = bit_array_segment_option_module(BitArrayOption::Native { 1485 location: SrcSpan::default(), 1486 }); 1487 assert_eq!(roundtrip(&module), module); 1488} 1489 1490#[test] 1491fn deprecated_type() { 1492 let module = ModuleInterface { 1493 warnings: vec![], 1494 is_internal: false, 1495 package: "some_package".into(), 1496 origin: Origin::Src, 1497 name: "a/b".into(), 1498 types: [( 1499 "ListIntType".into(), 1500 TypeConstructor { 1501 type_: type_::list(type_::int()), 1502 publicity: Publicity::Public, 1503 origin: SrcSpan::default(), 1504 module: "the/module".into(), 1505 parameters: vec![], 1506 deprecation: Deprecation::Deprecated { 1507 message: "oh no".into(), 1508 }, 1509 documentation: None, 1510 }, 1511 )] 1512 .into(), 1513 types_value_constructors: HashMap::new(), 1514 values: HashMap::new(), 1515 accessors: HashMap::new(), 1516 line_numbers: LineNumbers::new(""), 1517 src_path: "some_path".into(), 1518 minimum_required_version: Version::new(0, 1, 0), 1519 type_aliases: HashMap::new(), 1520 documentation: Vec::new(), 1521 contains_echo: false, 1522 1523 references: References::default(), 1524 inline_functions: HashMap::new(), 1525 }; 1526 assert_eq!(roundtrip(&module), module); 1527} 1528 1529#[test] 1530fn module_fn_value_with_external_implementations() { 1531 let module = ModuleInterface { 1532 warnings: vec![], 1533 is_internal: false, 1534 package: "some_package".into(), 1535 origin: Origin::Src, 1536 name: "a/b/c".into(), 1537 types: HashMap::new(), 1538 types_value_constructors: HashMap::new(), 1539 accessors: HashMap::new(), 1540 values: [( 1541 "one".into(), 1542 ValueConstructor { 1543 publicity: Publicity::Public, 1544 deprecation: Deprecation::NotDeprecated, 1545 type_: type_::int(), 1546 variant: ValueConstructorVariant::ModuleFn { 1547 documentation: Some("wabble!".into()), 1548 name: "one".into(), 1549 field_map: None, 1550 module: "a".into(), 1551 arity: 5, 1552 location: SrcSpan { 1553 start: 52, 1554 end: 1100, 1555 }, 1556 external_erlang: Some(("wibble".into(), "wobble".into())), 1557 external_javascript: Some(("wobble".into(), "wibble".into())), 1558 external_cranelift: None, 1559 implementations: Implementations { 1560 gleam: false, 1561 uses_erlang_externals: true, 1562 uses_javascript_externals: true, 1563 uses_cranelift_externals: false, 1564 can_run_on_erlang: false, 1565 can_run_on_javascript: true, 1566 can_run_on_cranelift: false, 1567 }, 1568 purity: Purity::Impure, 1569 }, 1570 }, 1571 )] 1572 .into(), 1573 line_numbers: LineNumbers::new(""), 1574 src_path: "some_path".into(), 1575 minimum_required_version: Version::new(0, 1, 0), 1576 type_aliases: HashMap::new(), 1577 documentation: Vec::new(), 1578 contains_echo: false, 1579 references: References::default(), 1580 inline_functions: HashMap::new(), 1581 }; 1582 1583 assert_eq!(roundtrip(&module), module); 1584} 1585 1586#[test] 1587fn module_containing_echo() { 1588 let module = ModuleInterface { 1589 warnings: vec![], 1590 is_internal: false, 1591 package: "some_package".into(), 1592 origin: Origin::Src, 1593 name: "a/b/c".into(), 1594 types: HashMap::new(), 1595 types_value_constructors: HashMap::new(), 1596 accessors: HashMap::new(), 1597 values: [].into(), 1598 line_numbers: LineNumbers::new(""), 1599 src_path: "some_path".into(), 1600 minimum_required_version: Version::new(0, 1, 0), 1601 type_aliases: HashMap::new(), 1602 documentation: Vec::new(), 1603 contains_echo: true, 1604 references: References::default(), 1605 inline_functions: HashMap::new(), 1606 }; 1607 1608 assert_eq!(roundtrip(&module), module); 1609} 1610 1611#[test] 1612fn internal_module_fn() { 1613 let module = ModuleInterface { 1614 warnings: vec![], 1615 is_internal: false, 1616 package: "some_package".into(), 1617 origin: Origin::Src, 1618 name: "a/b/c".into(), 1619 types: HashMap::new(), 1620 types_value_constructors: HashMap::new(), 1621 accessors: HashMap::new(), 1622 values: [( 1623 "one".into(), 1624 ValueConstructor { 1625 publicity: Publicity::Internal { 1626 attribute_location: None, 1627 }, 1628 deprecation: Deprecation::NotDeprecated, 1629 type_: type_::int(), 1630 variant: ValueConstructorVariant::ModuleFn { 1631 documentation: Some("wabble!".into()), 1632 name: "one".into(), 1633 field_map: None, 1634 module: "a".into(), 1635 arity: 5, 1636 location: SrcSpan { 1637 start: 52, 1638 end: 1100, 1639 }, 1640 external_erlang: Some(("wibble".into(), "wobble".into())), 1641 external_javascript: Some(("wobble".into(), "wibble".into())), 1642 external_cranelift: None, 1643 implementations: Implementations { 1644 gleam: false, 1645 uses_erlang_externals: true, 1646 uses_javascript_externals: true, 1647 uses_cranelift_externals: false, 1648 can_run_on_erlang: true, 1649 can_run_on_javascript: true, 1650 can_run_on_cranelift: false, 1651 }, 1652 purity: Purity::Unknown, 1653 }, 1654 }, 1655 )] 1656 .into(), 1657 line_numbers: LineNumbers::new(""), 1658 src_path: "some_path".into(), 1659 minimum_required_version: Version::new(0, 1, 0), 1660 type_aliases: HashMap::new(), 1661 documentation: Vec::new(), 1662 contains_echo: false, 1663 1664 references: References::default(), 1665 inline_functions: HashMap::new(), 1666 }; 1667 1668 assert_eq!(roundtrip(&module), module); 1669} 1670 1671#[test] 1672fn internal_annotated_module_fn() { 1673 let module = ModuleInterface { 1674 warnings: vec![], 1675 is_internal: false, 1676 package: "some_package".into(), 1677 origin: Origin::Src, 1678 name: "a/b/c".into(), 1679 types: HashMap::new(), 1680 types_value_constructors: HashMap::new(), 1681 accessors: HashMap::new(), 1682 values: [( 1683 "one".into(), 1684 ValueConstructor { 1685 publicity: Publicity::Internal { 1686 attribute_location: Some(SrcSpan { 1687 start: 11, 1688 end: 111, 1689 }), 1690 }, 1691 deprecation: Deprecation::NotDeprecated, 1692 type_: type_::int(), 1693 variant: ValueConstructorVariant::ModuleFn { 1694 documentation: Some("wabble!".into()), 1695 name: "one".into(), 1696 field_map: None, 1697 module: "a".into(), 1698 arity: 5, 1699 location: SrcSpan { 1700 start: 52, 1701 end: 1100, 1702 }, 1703 external_erlang: Some(("wibble".into(), "wobble".into())), 1704 external_javascript: Some(("wobble".into(), "wibble".into())), 1705 external_cranelift: None, 1706 implementations: Implementations { 1707 gleam: false, 1708 uses_erlang_externals: true, 1709 uses_javascript_externals: true, 1710 uses_cranelift_externals: false, 1711 can_run_on_erlang: true, 1712 can_run_on_javascript: true, 1713 can_run_on_cranelift: false, 1714 }, 1715 purity: Purity::Impure, 1716 }, 1717 }, 1718 )] 1719 .into(), 1720 line_numbers: LineNumbers::new(""), 1721 src_path: "some_path".into(), 1722 minimum_required_version: Version::new(0, 1, 0), 1723 type_aliases: HashMap::new(), 1724 documentation: Vec::new(), 1725 contains_echo: false, 1726 1727 references: References::default(), 1728 inline_functions: HashMap::new(), 1729 }; 1730 1731 assert_eq!(roundtrip(&module), module); 1732} 1733 1734// https://github.com/gleam-lang/gleam/issues/2599 1735#[test] 1736fn type_variable_ids_in_constructors_are_shared() { 1737 let module = ModuleInterface { 1738 warnings: vec![], 1739 is_internal: false, 1740 package: "some_package".into(), 1741 origin: Origin::Src, 1742 name: "a/b/c".into(), 1743 types: HashMap::new(), 1744 types_value_constructors: HashMap::from([( 1745 "SomeType".into(), 1746 TypeVariantConstructors { 1747 type_parameters_ids: vec![4, 5, 6], 1748 variants: vec![TypeValueConstructor { 1749 name: "One".into(), 1750 parameters: vec![ 1751 TypeValueConstructorField { 1752 type_: type_::generic_var(6), 1753 label: None, 1754 documentation: Some("Here's some documentation".into()), 1755 }, 1756 TypeValueConstructorField { 1757 type_: type_::int(), 1758 label: None, 1759 documentation: None, 1760 }, 1761 TypeValueConstructorField { 1762 type_: type_::tuple(vec![type_::generic_var(4), type_::generic_var(5)]), 1763 label: None, 1764 documentation: None, 1765 }, 1766 ], 1767 documentation: None, 1768 }], 1769 opaque: Opaque::NotOpaque, 1770 }, 1771 )]), 1772 accessors: HashMap::new(), 1773 values: [].into(), 1774 line_numbers: LineNumbers::new(""), 1775 src_path: "some_path".into(), 1776 minimum_required_version: Version::new(0, 1, 0), 1777 type_aliases: HashMap::new(), 1778 documentation: Vec::new(), 1779 contains_echo: false, 1780 1781 references: References::default(), 1782 inline_functions: HashMap::new(), 1783 }; 1784 1785 let expected = HashMap::from([( 1786 "SomeType".into(), 1787 TypeVariantConstructors { 1788 type_parameters_ids: vec![0, 1, 2], 1789 variants: vec![TypeValueConstructor { 1790 name: "One".into(), 1791 parameters: vec![ 1792 TypeValueConstructorField { 1793 type_: type_::generic_var(2), 1794 label: None, 1795 documentation: Some("Here's some documentation".into()), 1796 }, 1797 TypeValueConstructorField { 1798 type_: type_::int(), 1799 label: None, 1800 documentation: None, 1801 }, 1802 TypeValueConstructorField { 1803 type_: type_::tuple(vec![type_::generic_var(0), type_::generic_var(1)]), 1804 label: None, 1805 documentation: None, 1806 }, 1807 ], 1808 documentation: None, 1809 }], 1810 opaque: Opaque::NotOpaque, 1811 }, 1812 )]); 1813 1814 assert_eq!(roundtrip(&module).types_value_constructors, expected); 1815} 1816 1817#[test] 1818fn type_with_inferred_variant() { 1819 let module = ModuleInterface { 1820 warnings: vec![], 1821 is_internal: false, 1822 package: "some_package".into(), 1823 contains_echo: false, 1824 origin: Origin::Src, 1825 name: "a/b".into(), 1826 types: [( 1827 "Wibble".into(), 1828 TypeConstructor { 1829 type_: Arc::new(Type::Named { 1830 publicity: Publicity::Internal { 1831 attribute_location: None, 1832 }, 1833 package: "some_package".into(), 1834 module: "the/module".into(), 1835 name: "Wibble".into(), 1836 arguments: Vec::new(), 1837 inferred_variant: Some(1), 1838 }), 1839 publicity: Publicity::Internal { 1840 attribute_location: Some(SrcSpan::new(0, 10)), 1841 }, 1842 origin: SrcSpan::default(), 1843 module: "the/module".into(), 1844 parameters: vec![], 1845 deprecation: Deprecation::NotDeprecated, 1846 documentation: None, 1847 }, 1848 )] 1849 .into(), 1850 types_value_constructors: HashMap::new(), 1851 values: HashMap::new(), 1852 accessors: HashMap::new(), 1853 line_numbers: LineNumbers::new(""), 1854 src_path: "some_path".into(), 1855 minimum_required_version: Version::new(0, 1, 0), 1856 type_aliases: HashMap::new(), 1857 documentation: Vec::new(), 1858 references: References::default(), 1859 inline_functions: HashMap::new(), 1860 }; 1861 assert_eq!(roundtrip(&module), module); 1862} 1863 1864#[test] 1865fn module_with_type_aliases() { 1866 let module = ModuleInterface { 1867 warnings: vec![], 1868 is_internal: false, 1869 package: "some_package".into(), 1870 origin: Origin::Src, 1871 name: "some_module".into(), 1872 types: HashMap::new(), 1873 types_value_constructors: HashMap::new(), 1874 values: HashMap::new(), 1875 accessors: HashMap::new(), 1876 line_numbers: LineNumbers::new(""), 1877 src_path: "some_path".into(), 1878 minimum_required_version: Version::new(0, 1, 0), 1879 type_aliases: [( 1880 "MyAlias".into(), 1881 TypeAliasConstructor { 1882 publicity: Publicity::Public, 1883 module: "some_module".into(), 1884 type_: prelude::int(), 1885 arity: 1, 1886 deprecation: Deprecation::NotDeprecated, 1887 documentation: Some("Some documentation".into()), 1888 origin: SrcSpan::default(), 1889 parameters: vec![type_::generic_var(0)], 1890 }, 1891 )] 1892 .into(), 1893 documentation: Vec::new(), 1894 contains_echo: false, 1895 1896 references: References::default(), 1897 inline_functions: HashMap::new(), 1898 }; 1899 assert_eq!(roundtrip(&module), module); 1900} 1901 1902#[test] 1903fn module_with_documentation() { 1904 let module = ModuleInterface { 1905 warnings: vec![], 1906 is_internal: false, 1907 package: "some_package".into(), 1908 origin: Origin::Src, 1909 name: "some_module".into(), 1910 types: HashMap::new(), 1911 types_value_constructors: HashMap::new(), 1912 values: HashMap::new(), 1913 accessors: HashMap::new(), 1914 line_numbers: LineNumbers::new(""), 1915 src_path: "some_path".into(), 1916 minimum_required_version: Version::new(0, 1, 0), 1917 type_aliases: HashMap::new(), 1918 documentation: vec![ 1919 "This is a line of documentation".into(), 1920 "And here is another".into(), 1921 "And finally, a third".into(), 1922 ], 1923 contains_echo: false, 1924 1925 references: References::default(), 1926 inline_functions: HashMap::new(), 1927 }; 1928 assert_eq!(roundtrip(&module), module); 1929} 1930 1931#[test] 1932fn module_with_opaque_type() { 1933 let module = ModuleInterface { 1934 warnings: vec![], 1935 is_internal: false, 1936 package: "some_package".into(), 1937 origin: Origin::Src, 1938 name: "a".into(), 1939 types: HashMap::new(), 1940 types_value_constructors: [( 1941 "SomeType".into(), 1942 TypeVariantConstructors { 1943 type_parameters_ids: vec![0, 1, 2], 1944 variants: vec![TypeValueConstructor { 1945 name: "One".into(), 1946 parameters: vec![], 1947 documentation: Some("Some documentation".into()), 1948 }], 1949 opaque: Opaque::Opaque, 1950 }, 1951 )] 1952 .into(), 1953 accessors: HashMap::new(), 1954 values: HashMap::new(), 1955 line_numbers: LineNumbers::new(""), 1956 src_path: "some_path".into(), 1957 minimum_required_version: Version::new(0, 1, 0), 1958 type_aliases: HashMap::new(), 1959 documentation: Vec::new(), 1960 contains_echo: false, 1961 references: References::default(), 1962 inline_functions: HashMap::new(), 1963 }; 1964 1965 assert_eq!(roundtrip(&module), module); 1966} 1967 1968#[test] 1969fn module_with_references() { 1970 let module = ModuleInterface { 1971 warnings: vec![], 1972 is_internal: false, 1973 package: "some_package".into(), 1974 origin: Origin::Src, 1975 name: "a".into(), 1976 types: HashMap::new(), 1977 types_value_constructors: HashMap::new(), 1978 accessors: HashMap::new(), 1979 values: HashMap::new(), 1980 line_numbers: LineNumbers::new(""), 1981 src_path: "some_path".into(), 1982 minimum_required_version: Version::new(0, 1, 0), 1983 type_aliases: HashMap::new(), 1984 documentation: Vec::new(), 1985 contains_echo: false, 1986 references: References { 1987 imported_modules: ["some_module".into(), "some_other_module".into()].into(), 1988 value_references: [ 1989 ( 1990 ("some_module".into(), "some_function".into()), 1991 vec![ 1992 Reference { 1993 location: SrcSpan::new(1, 6), 1994 kind: ReferenceKind::Definition, 1995 }, 1996 Reference { 1997 location: SrcSpan::new(7, 11), 1998 kind: ReferenceKind::Unqualified, 1999 }, 2000 ], 2001 ), 2002 ( 2003 ("some_other_module".into(), "some_constant".into()), 2004 vec![ 2005 Reference { 2006 location: SrcSpan::new(6, 9), 2007 kind: ReferenceKind::Import(SrcSpan::new(9, 9)), 2008 }, 2009 Reference { 2010 location: SrcSpan::new(90, 108), 2011 kind: ReferenceKind::Unqualified, 2012 }, 2013 ], 2014 ), 2015 ( 2016 ("some_other_module".into(), "SomeTypeVariant".into()), 2017 vec![ 2018 Reference { 2019 location: SrcSpan::new(26, 35), 2020 kind: ReferenceKind::Qualified { 2021 module_alias: "some_other_module".into(), 2022 module_location: SrcSpan::new(26, 29), 2023 }, 2024 }, 2025 Reference { 2026 location: SrcSpan::new(152, 204), 2027 kind: ReferenceKind::Qualified { 2028 module_alias: "some_other_module".into(), 2029 module_location: SrcSpan::new(26, 29), 2030 }, 2031 }, 2032 Reference { 2033 location: SrcSpan::new(0, 8), 2034 kind: ReferenceKind::Qualified { 2035 module_alias: "some_alias".into(), 2036 module_location: SrcSpan::new(26, 29), 2037 }, 2038 }, 2039 ], 2040 ), 2041 ] 2042 .into(), 2043 type_references: [( 2044 ("some_other_module".into(), "TypeVariant".into()), 2045 vec![ 2046 Reference { 2047 location: SrcSpan::new(26, 35), 2048 kind: ReferenceKind::Qualified { 2049 module_alias: "some_alias".into(), 2050 module_location: SrcSpan::new(26, 29), 2051 }, 2052 }, 2053 Reference { 2054 location: SrcSpan::new(152, 204), 2055 kind: ReferenceKind::Unqualified, 2056 }, 2057 Reference { 2058 location: SrcSpan::new(0, 8), 2059 kind: ReferenceKind::Definition, 2060 }, 2061 ], 2062 )] 2063 .into(), 2064 module_references: [( 2065 "some_module".into(), 2066 vec![ 2067 ModuleNameReference::Import { 2068 module_location: SrcSpan::new(5, 20), 2069 import_end: 31, 2070 }, 2071 ModuleNameReference::AliasedImport { 2072 module_location: SrcSpan::new(5, 20), 2073 alias_location: SrcSpan::new(26, 32), 2074 alias: "some_alias".into(), 2075 }, 2076 ModuleNameReference::ModuleSelect(SrcSpan::new(92, 100)), 2077 ModuleNameReference::AliasedModuleSelect(SrcSpan::new(152, 160)), 2078 ], 2079 )] 2080 .into(), 2081 label_references: HashMap::new(), 2082 label_definitions: HashMap::new(), 2083 }, 2084 inline_functions: HashMap::new(), 2085 }; 2086 2087 assert_eq!(roundtrip(&module), module); 2088}