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

Configure Feed

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

aggressive caching

author
Giacomo Cavalieri
committer
Louis Pilfold
date (Jun 15, 2026, 12:37 PM +0100) commit df74d94d parent 903d425d change-id krlywzls
+555 -285
+555 -285
compiler-core/src/format.rs
··· 31 31 pub struct FormatterCache<'doc, 'a> { 32 32 nil: Document<'doc, 'a>, 33 33 space: Document<'doc, 'a>, 34 - 35 34 empty_break: Document<'doc, 'a>, 36 35 breakable_space: Document<'doc, 'a>, 37 - 36 + flex_comma: Document<'doc, 'a>, 37 + comma_break: Document<'doc, 'a>, 38 + trailing_comma_break: Document<'doc, 'a>, 38 39 line: Document<'doc, 'a>, 39 40 two_lines: Document<'doc, 'a>, 41 + module_comment: Document<'doc, 'a>, 42 + doc_comment: Document<'doc, 'a>, 43 + comment: Document<'doc, 'a>, 44 + const_space: Document<'doc, 'a>, 45 + opaque_type_space: Document<'doc, 'a>, 46 + type_space: Document<'doc, 'a>, 47 + echo_space: Document<'doc, 'a>, 48 + import_space: Document<'doc, 'a>, 49 + assert_space: Document<'doc, 'a>, 50 + as_: Document<'doc, 'a>, 51 + space_as: Document<'doc, 'a>, 52 + space_as_space: Document<'doc, 'a>, 53 + space_equal_space: Document<'doc, 'a>, 54 + todo: Document<'doc, 'a>, 55 + concat: Document<'doc, 'a>, 56 + use_: Document<'doc, 'a>, 57 + use_and_arrow: Document<'doc, 'a>, 58 + left_arrow: Document<'doc, 'a>, 59 + minus_space: Document<'doc, 'a>, 60 + exclamation_mark: Document<'doc, 'a>, 61 + pipe_space: Document<'doc, 'a>, 62 + colon: Document<'doc, 'a>, 63 + dot: Document<'doc, 'a>, 64 + hashtag: Document<'doc, 'a>, 65 + dot_dot: Document<'doc, 'a>, 66 + colon_space: Document<'doc, 'a>, 67 + open_curly: Document<'doc, 'a>, 68 + open_curly_break: Document<'doc, 'a>, 69 + space_open_curly: Document<'doc, 'a>, 70 + close_curly: Document<'doc, 'a>, 71 + open_square: Document<'doc, 'a>, 72 + open_square_break: Document<'doc, 'a>, 73 + close_square: Document<'doc, 'a>, 74 + open_close_square: Document<'doc, 'a>, 75 + open_paren: Document<'doc, 'a>, 76 + open_paren_break: Document<'doc, 'a>, 77 + close_paren: Document<'doc, 'a>, 78 + open_close_paren: Document<'doc, 'a>, 79 + empty_tuple: Document<'doc, 'a>, 80 + open_tuple: Document<'doc, 'a>, 81 + open_tuple_break: Document<'doc, 'a>, 82 + fn_: Document<'doc, 'a>, 83 + fn_space: Document<'doc, 'a>, 84 + panic: Document<'doc, 'a>, 85 + if_space: Document<'doc, 'a>, 86 + space_right_arrow: Document<'doc, 'a>, 87 + space_right_arrow_space: Document<'doc, 'a>, 88 + let_space: Document<'doc, 'a>, 89 + let_assert_space: Document<'doc, 'a>, 90 + space_equal: Document<'doc, 'a>, 91 + underscore: Document<'doc, 'a>, 92 + double_quote: Document<'doc, 'a>, 93 + open_paren_dot_dot_close_paren: Document<'doc, 'a>, 94 + vertical_bar_space: Document<'doc, 'a>, 95 + space_concat_space: Document<'doc, 'a>, 96 + space_plus_space: Document<'doc, 'a>, 97 + space_minus_space: Document<'doc, 'a>, 98 + space_times_space: Document<'doc, 'a>, 99 + space_module_space: Document<'doc, 'a>, 100 + space_slash_space: Document<'doc, 'a>, 101 + space_close_curly: Document<'doc, 'a>, 102 + open_curly_space: Document<'doc, 'a>, 103 + close_bit_array: Document<'doc, 'a>, 104 + open_bit_array_break: Document<'doc, 'a>, 105 + echo: Document<'doc, 'a>, 106 + empty_bit_array: Document<'doc, 'a>, 107 + open_bit_array: Document<'doc, 'a>, 108 + right_arrow: Document<'doc, 'a>, 109 + pub_space: Document<'doc, 'a>, 110 + value: Document<'doc, 'a>, 111 + size: Document<'doc, 'a>, 112 + bytes: Document<'doc, 'a>, 113 + bits: Document<'doc, 'a>, 114 + int: Document<'doc, 'a>, 115 + float: Document<'doc, 'a>, 116 + utf8: Document<'doc, 'a>, 117 + utf16: Document<'doc, 'a>, 118 + utf32: Document<'doc, 'a>, 119 + utf8_codepoint: Document<'doc, 'a>, 120 + utf16_codepoint: Document<'doc, 'a>, 121 + utf32_codepoint: Document<'doc, 'a>, 122 + signed: Document<'doc, 'a>, 123 + unsigned: Document<'doc, 'a>, 124 + big: Document<'doc, 'a>, 125 + little: Document<'doc, 'a>, 126 + native: Document<'doc, 'a>, 127 + and: Document<'doc, 'a>, 128 + or: Document<'doc, 'a>, 129 + lt_int: Document<'doc, 'a>, 130 + lt_eq_int: Document<'doc, 'a>, 131 + lt_float: Document<'doc, 'a>, 132 + lt_eq_float: Document<'doc, 'a>, 133 + eq: Document<'doc, 'a>, 134 + not_eq: Document<'doc, 'a>, 135 + gt_eq_int: Document<'doc, 'a>, 136 + gt_int: Document<'doc, 'a>, 137 + gt_eq_float: Document<'doc, 'a>, 138 + gt_float: Document<'doc, 'a>, 139 + add_int: Document<'doc, 'a>, 140 + add_float: Document<'doc, 'a>, 141 + sub_int: Document<'doc, 'a>, 142 + sub_float: Document<'doc, 'a>, 143 + mult_int: Document<'doc, 'a>, 144 + mult_float: Document<'doc, 'a>, 145 + div_int: Document<'doc, 'a>, 146 + div_float: Document<'doc, 'a>, 147 + remainder_int: Document<'doc, 'a>, 40 148 } 41 149 42 150 impl<'doc, 'a> FormatterCache<'doc, 'a> { ··· 46 154 space: " ".to_doc(arena), 47 155 empty_break: arena.break_("", ""), 48 156 breakable_space: arena.break_("", " "), 157 + flex_comma: arena.flex_break(",", ", "), 158 + comma_break: arena.break_(",", ", "), 159 + trailing_comma_break: arena.break_(",", ""), 49 160 line: arena.line(), 50 161 two_lines: arena.lines(2), 162 + module_comment: "////".to_doc(arena), 163 + doc_comment: "///".to_doc(arena), 164 + const_space: "const ".to_doc(arena), 165 + opaque_type_space: "opaque type ".to_doc(arena), 166 + type_space: "type ".to_doc(arena), 167 + import_space: "import ".to_doc(arena), 168 + space_as_space: " as ".to_doc(arena), 169 + space_equal_space: " = ".to_doc(arena), 170 + todo: "todo".to_doc(arena), 171 + concat: "<>".to_doc(arena), 172 + dot: ".".to_doc(arena), 173 + dot_dot: "..".to_doc(arena), 174 + colon_space: ": ".to_doc(arena), 175 + open_curly: "{".to_doc(arena), 176 + open_curly_break: arena.break_("{", "{ "), 177 + close_curly: "}".to_doc(arena), 178 + open_square: "[".to_doc(arena), 179 + open_square_break: arena.break_("[", "["), 180 + close_square: "]".to_doc(arena), 181 + open_close_square: "[]".to_doc(arena), 182 + comment: "//".to_doc(arena), 183 + echo_space: "echo ".to_doc(arena), 184 + as_: "as".to_doc(arena), 185 + space_as: " as".to_doc(arena), 186 + open_paren: "(".to_doc(arena), 187 + open_paren_break: arena.break_("(", "("), 188 + close_paren: ")".to_doc(arena), 189 + open_close_paren: "()".to_doc(arena), 190 + use_: "use".to_doc(arena), 191 + use_and_arrow: "use <-".to_doc(arena), 192 + left_arrow: "<-".to_doc(arena), 193 + minus_space: "- ".to_doc(arena), 194 + exclamation_mark: "!".to_doc(arena), 195 + assert_space: "assert ".to_doc(arena), 196 + pipe_space: "|> ".to_doc(arena), 197 + colon: ":".to_doc(arena), 198 + hashtag: "#".to_doc(arena), 199 + space_open_curly: " {".to_doc(arena), 200 + empty_tuple: "#()".to_doc(arena), 201 + open_tuple: "#(".to_doc(arena), 202 + open_tuple_break: arena.break_("#(", "#("), 203 + fn_: "fn".to_doc(arena), 204 + fn_space: "fn ".to_doc(arena), 205 + panic: "panic".to_doc(arena), 206 + if_space: "if ".to_doc(arena), 207 + space_right_arrow: " ->".to_doc(arena), 208 + space_right_arrow_space: " -> ".to_doc(arena), 209 + let_space: "let ".to_doc(arena), 210 + let_assert_space: "let assert ".to_doc(arena), 211 + space_equal: " =".to_doc(arena), 212 + underscore: "_".to_doc(arena), 213 + double_quote: "\"".to_doc(arena), 214 + open_paren_dot_dot_close_paren: "(..)".to_doc(arena), 215 + vertical_bar_space: "| ".to_doc(arena), 216 + space_concat_space: " <> ".to_doc(arena), 217 + space_plus_space: " + ".to_doc(arena), 218 + space_minus_space: " - ".to_doc(arena), 219 + space_times_space: " * ".to_doc(arena), 220 + space_module_space: " % ".to_doc(arena), 221 + space_slash_space: " / ".to_doc(arena), 222 + space_close_curly: " }".to_doc(arena), 223 + open_curly_space: "{ ".to_doc(arena), 224 + close_bit_array: ">>".to_doc(arena), 225 + open_bit_array_break: arena.break_("<<", "<<"), 226 + echo: "echo".to_doc(arena), 227 + empty_bit_array: "<<>>".to_doc(arena), 228 + open_bit_array: "<<".to_doc(arena), 229 + right_arrow: "->".to_doc(arena), 230 + pub_space: "pub ".to_doc(arena), 231 + value: "value".to_doc(arena), 232 + size: "size".to_doc(arena), 233 + bytes: "bytes".to_doc(arena), 234 + bits: "bits".to_doc(arena), 235 + int: "int".to_doc(arena), 236 + float: "float".to_doc(arena), 237 + utf8: "utf8".to_doc(arena), 238 + utf16: "utf16".to_doc(arena), 239 + utf32: "utf32".to_doc(arena), 240 + utf8_codepoint: "utf8_codepoint".to_doc(arena), 241 + utf16_codepoint: "utf16_codepoint".to_doc(arena), 242 + utf32_codepoint: "utf32_codepoint".to_doc(arena), 243 + signed: "signed".to_doc(arena), 244 + unsigned: "unsigned".to_doc(arena), 245 + big: "big".to_doc(arena), 246 + little: "little".to_doc(arena), 247 + native: "native".to_doc(arena), 248 + and: "&&".to_doc(arena), 249 + or: "||".to_doc(arena), 250 + lt_int: "<".to_doc(arena), 251 + lt_eq_int: "<=".to_doc(arena), 252 + lt_float: "<.".to_doc(arena), 253 + lt_eq_float: "<=.".to_doc(arena), 254 + eq: "==".to_doc(arena), 255 + not_eq: "!=".to_doc(arena), 256 + gt_eq_int: ">=".to_doc(arena), 257 + gt_int: ">".to_doc(arena), 258 + gt_eq_float: ">=.".to_doc(arena), 259 + gt_float: ">.".to_doc(arena), 260 + add_int: "+".to_doc(arena), 261 + add_float: "+.".to_doc(arena), 262 + sub_int: "-".to_doc(arena), 263 + sub_float: "-.".to_doc(arena), 264 + mult_int: "*".to_doc(arena), 265 + mult_float: "*.".to_doc(arena), 266 + div_int: "/".to_doc(arena), 267 + div_float: "/.".to_doc(arena), 268 + remainder_int: "%".to_doc(arena), 51 269 } 52 270 } 53 271 } ··· 295 513 // with any statement, and are moved to the bottom of the module. 296 514 let doc_comments = arena.join( 297 515 self.doc_comments.iter().map(|comment| { 298 - "///" 516 + cache 517 + .doc_comment 299 518 .to_doc(arena) 300 519 .append(arena, EcoString::from(comment.content)) 301 520 }), ··· 310 529 311 530 let module_comments = if !self.module_comments.is_empty() { 312 531 let comments = self.module_comments.iter().map(|s| { 313 - "////" 532 + cache 533 + .module_comment 314 534 .to_doc(arena) 315 535 .append(arena, EcoString::from(s.content)) 316 536 }); ··· 455 675 let unqualified_types = unqualified_types 456 676 .iter() 457 677 .sorted_by(|a, b| a.name.cmp(&b.name)) 458 - .map(|type_| docvec_ref_arena![arena, "type ", type_]); 678 + .map(|type_| docvec_ref_arena![arena, cache.type_space, type_]); 459 679 let unqualified_values = unqualified_values 460 680 .iter() 461 681 .sorted_by(|a, b| a.name.cmp(&b.name)) 462 682 .map(|value| value.to_doc(arena)); 463 683 let unqualified = arena.join( 464 684 unqualified_types.chain(unqualified_values), 465 - arena.flex_break(",", ", "), 685 + cache.flex_comma, 466 686 ); 467 - let unqualified = arena 468 - .break_("", "") 687 + let unqualified = cache 688 + .empty_break 469 689 .append(arena, unqualified) 470 690 .nest(arena, INDENT) 471 - .append(arena, arena.break_(",", "")) 691 + .append(arena, cache.trailing_comma_break) 472 692 .group(arena); 473 693 ".{".to_doc(arena) 474 694 .append(arena, unqualified) 475 - .append(arena, "}") 695 + .append(arena, cache.close_curly) 476 696 }; 477 697 478 - let doc = docvec_ref_arena![arena, "import ", module.as_str(), second]; 698 + let doc = docvec_ref_arena![arena, cache.import_space, module.as_str(), second]; 479 699 let default_module_access_name = module.split('/').next_back().map(EcoString::from); 480 700 match (default_module_access_name, as_name) { 481 701 // If the `as name` is the same as the module name that would be ··· 491 711 } 492 712 (_, None) => doc, 493 713 (_, Some((AssignName::Variable(name) | AssignName::Discard(name), _))) => { 494 - doc.append(arena, " as ").append(arena, name) 714 + doc.append(arena, cache.space_as_space).append(arena, name) 495 715 } 496 716 } 497 717 } ··· 513 733 .set_deprecation(deprecation) 514 734 .to_doc(arena); 515 735 let head = attributes 516 - .append(arena, pub_(arena, cache, *publicity)) 517 - .append(arena, "const ") 736 + .append(arena, pub_(cache, *publicity)) 737 + .append(arena, cache.const_space) 518 738 .append(arena, name.as_str()); 519 739 let head = match annotation { 520 740 None => head, 521 741 Some(type_) => head 522 - .append(arena, ": ") 742 + .append(arena, cache.colon_space) 523 743 .append(arena, self.type_ast(arena, cache, type_)), 524 744 }; 525 - head.append(arena, " = ") 745 + head.append(arena, cache.space_equal_space) 526 746 .append(arena, self.const_expr(arena, cache, value).group(arena)) 527 747 } 528 748 } ··· 536 756 ) -> Document<'a, 'doc> { 537 757 let comments = self.pop_comments(value.location().start); 538 758 let document = match value { 539 - Constant::Todo { message, .. } => self.append_as_message_constant( 540 - arena, 541 - cache, 542 - "todo".to_doc(arena), 543 - message.as_deref(), 544 - ), 759 + Constant::Todo { message, .. } => { 760 + self.append_as_message_constant(arena, cache, cache.todo, message.as_deref()) 761 + } 545 762 546 763 Constant::Int { value, .. } => self.int(arena, cache, value), 547 764 ··· 596 813 .. 597 814 } => module 598 815 .to_doc(arena) 599 - .append(arena, ".") 816 + .append(arena, cache.dot) 600 817 .append(arena, name.as_str()), 601 818 602 819 Constant::Record { ··· 631 848 .collect_vec(); 632 849 module 633 850 .to_doc(arena) 634 - .append(arena, ".") 851 + .append(arena, cache.dot) 635 852 .append(arena, name.as_str()) 636 853 .append( 637 854 arena, ··· 648 865 name, 649 866 module: Some((module, _)), 650 867 .. 651 - } => docvec_ref_arena![arena, module, ".", name], 868 + } => docvec_ref_arena![arena, module, cache.dot, name], 652 869 653 870 Constant::StringConcatenation { left, right, .. } => self 654 871 .const_expr(arena, cache, left) 655 - .append( 656 - arena, 657 - cache.breakable_space.append(arena, "<>".to_doc(arena)), 658 - ) 872 + .append(arena, cache.breakable_space.append(arena, cache.concat)) 659 873 .nest(arena, INDENT) 660 874 .append(arena, cache.space) 661 875 .append(arena, self.const_expr(arena, cache, right)), ··· 688 902 // any comment we want to put it inside the empty list! 689 903 let comments = self.pop_comments(location.end); 690 904 return match printed_comments(arena, cache, comments, false) { 691 - None => "[]".to_doc(arena), 692 - Some(comments) => "[" 693 - .to_doc(arena) 905 + None => cache.open_close_square, 906 + Some(comments) => cache 907 + .open_square 694 908 .append(arena, cache.empty_break.nest(arena, INDENT)) 695 909 .append(arena, comments) 696 910 .append(arena, cache.empty_break) 697 - .append(arena, "]") 911 + .append(arena, cache.close_square) 698 912 // vvv We want to make sure the comments are on a separate 699 913 // line from the opening and closing brackets so we 700 914 // force the breaks to be split on newlines. ··· 709 923 *location, 710 924 ); 711 925 let comma = match list_packing { 712 - ItemsPacking::FitMultiplePerLine => arena.flex_break(",", ", "), 713 - ItemsPacking::FitOnePerLine | ItemsPacking::BreakOnePerLine => arena.break_(",", ", "), 926 + ItemsPacking::FitMultiplePerLine => cache.flex_comma, 927 + ItemsPacking::FitOnePerLine | ItemsPacking::BreakOnePerLine => cache.comma_break, 714 928 }; 715 929 716 930 let mut elements_doc = cache.nil; ··· 738 952 } 739 953 elements_doc = elements_doc.next_break_fits(arena, NextBreakFitsMode::Disabled); 740 954 741 - let doc = arena.break_("[", "[").append(arena, elements_doc); 955 + let doc = cache.open_square_break.append(arena, elements_doc); 742 956 let (doc, final_break) = match tail { 743 - None => (doc.nest(arena, INDENT), arena.break_(",", "")), 957 + None => (doc.nest(arena, INDENT), cache.trailing_comma_break), 744 958 Some(tail) => { 745 959 let comments = self.pop_comments(tail.location().start); 746 960 747 961 let tail = commented( 748 962 arena, 749 963 cache, 750 - docvec_ref_arena![arena, "..", self.const_expr(arena, cache, tail)], 964 + docvec_ref_arena![arena, cache.dot_dot, self.const_expr(arena, cache, tail)], 751 965 comments, 752 966 ); 753 967 ( 754 - doc.append(arena, arena.break_(",", ", ")) 968 + doc.append(arena, cache.comma_break) 755 969 .append(arena, tail) 756 970 .nest(arena, INDENT), 757 971 cache.empty_break, ··· 766 980 // Otherwise those would be moved out of the list. 767 981 let comments = self.pop_comments(location.end); 768 982 let doc = match printed_comments(arena, cache, comments, false) { 769 - None => doc.append(arena, final_break).append(arena, "]"), 983 + None => doc 984 + .append(arena, final_break) 985 + .append(arena, cache.close_square), 770 986 Some(comment) => doc 771 987 .append(arena, final_break.nest(arena, INDENT)) 772 988 // ^ See how here we're adding the missing indentation to the ··· 774 990 // list's items. 775 991 .append(arena, comment) 776 992 .append(arena, cache.line) 777 - .append(arena, "]") 993 + .append(arena, cache.close_square) 778 994 .force_break(arena), 779 995 }; 780 996 ··· 797 1013 // any comment we want to put it inside the empty list! 798 1014 let comments = self.pop_comments(location.end); 799 1015 return match printed_comments(arena, cache, comments, false) { 800 - None => "#()".to_doc(arena), 801 - Some(comments) => "#(" 802 - .to_doc(arena) 1016 + None => cache.empty_tuple, 1017 + Some(comments) => cache 1018 + .open_tuple 803 1019 .append(arena, cache.empty_break.nest(arena, INDENT)) 804 1020 .append(arena, comments) 805 1021 .append(arena, cache.empty_break) 806 - .append(arena, ")") 1022 + .append(arena, cache.close_paren) 807 1023 // vvv We want to make sure the comments are on a separate 808 1024 // line from the opening and closing parentheses so we 809 1025 // force the breaks to be split on newlines. ··· 814 1030 let arguments_docs = elements 815 1031 .iter() 816 1032 .map(|element| self.const_expr(arena, cache, element)); 817 - let tuple_doc = arena 818 - .break_("#(", "#(") 1033 + let tuple_doc = cache 1034 + .open_tuple_break 819 1035 .append( 820 1036 arena, 821 1037 arena 822 - .join(arguments_docs, arena.break_(",", ", ")) 1038 + .join(arguments_docs, cache.comma_break) 823 1039 .next_break_fits(arena, NextBreakFitsMode::Disabled), 824 1040 ) 825 1041 .nest(arena, INDENT); ··· 827 1043 let comments = self.pop_comments(location.end); 828 1044 match printed_comments(arena, cache, comments, false) { 829 1045 None => tuple_doc 830 - .append(arena, arena.break_(",", "")) 831 - .append(arena, ")") 1046 + .append(arena, cache.trailing_comma_break) 1047 + .append(arena, cache.close_paren) 832 1048 .group(arena), 833 1049 Some(comments) => tuple_doc 834 - .append(arena, arena.break_(",", "").nest(arena, INDENT)) 1050 + .append(arena, cache.trailing_comma_break.nest(arena, INDENT)) 835 1051 .append(arena, comments) 836 1052 .append(arena, cache.line) 837 - .append(arena, ")") 1053 + .append(arena, cache.close_paren) 838 1054 .force_break(arena), 839 1055 } 840 1056 } ··· 866 1082 Some(_) => arena 867 1083 .join( 868 1084 comments.map(|comment| match comment { 869 - Some(comment) => { 870 - "///".to_doc(arena).append(arena, EcoString::from(comment)) 871 - } 1085 + Some(comment) => cache.doc_comment.append(arena, EcoString::from(comment)), 872 1086 None => unreachable!("empty lines dropped by pop_doc_comments"), 873 1087 }), 874 1088 cache.line, ··· 889 1103 let head = match name { 890 1104 TypeAstConstructorName::Unqualified { name, .. } => name.to_doc(arena), 891 1105 TypeAstConstructorName::Qualified { module, name, .. } => { 892 - module.to_doc(arena).append(arena, ".").append( 1106 + module.to_doc(arena).append(arena, cache.dot).append( 893 1107 arena, 894 1108 name.as_ref() 895 1109 .map_or(cache.nil, |(name, _name_location)| name.to_doc(arena)), ··· 929 1143 arguments, 930 1144 return_, 931 1145 location, 932 - }) => "fn" 933 - .to_doc(arena) 1146 + }) => cache 1147 + .fn_ 934 1148 .append( 935 1149 arena, 936 1150 self.type_arguments(arena, cache, arguments, location), 937 1151 ) 938 1152 .group(arena) 939 - .append(arena, " ->") 1153 + .append(arena, cache.space_right_arrow) 940 1154 .append( 941 1155 arena, 942 1156 cache ··· 948 1162 949 1163 TypeAst::Var(TypeAstVar { name, .. }) => name.to_doc(arena), 950 1164 951 - TypeAst::Tuple(TypeAstTuple { elements, location }) => "#" 952 - .to_doc(arena) 1165 + TypeAst::Tuple(TypeAstTuple { elements, location }) => cache 1166 + .hashtag 953 1167 .append(arena, self.type_arguments(arena, cache, elements, location)), 954 1168 }; 955 1169 ··· 996 1210 let head = docvec_ref_arena![ 997 1211 arena, 998 1212 attributes, 999 - pub_(arena, cache, *publicity), 1000 - "type ", 1213 + pub_(cache, *publicity), 1214 + cache.type_space, 1001 1215 name 1002 1216 ]; 1003 1217 let head = if arguments.is_empty() { ··· 1033 1247 Some(type_) => argument 1034 1248 .names 1035 1249 .to_doc(arena) 1036 - .append(arena, ": ") 1250 + .append(arena, cache.colon_space) 1037 1251 .append(arena, self.type_ast(arena, cache, type_)), 1038 1252 } 1039 1253 .group(arena); ··· 1076 1290 .iter() 1077 1291 .map(|argument| self.fn_arg(arena, cache, argument)) 1078 1292 .collect_vec(); 1079 - let signature = pub_(arena, cache, *publicity) 1080 - .append(arena, "fn ") 1293 + let signature = pub_(cache, *publicity) 1294 + .append(arena, cache.fn_space) 1081 1295 .append( 1082 1296 arena, 1083 1297 &name ··· 1102 1316 // Add return annotation 1103 1317 let signature = match &return_annotation { 1104 1318 Some(annotation) => signature 1105 - .append(arena, " -> ") 1319 + .append(arena, cache.space_right_arrow_space) 1106 1320 .append(arena, self.type_ast(arena, cache, annotation)), 1107 1321 None => signature, 1108 1322 }; ··· 1121 1335 1122 1336 // Stick it all together 1123 1337 let function = signature 1124 - .append(arena, " {") 1338 + .append(arena, cache.space_open_curly) 1125 1339 .group(arena) 1126 1340 .append( 1127 1341 arena, ··· 1132 1346 .group(arena), 1133 1347 ) 1134 1348 .append(arena, cache.line) 1135 - .append(arena, "}"); 1349 + .append(arena, cache.close_curly); 1136 1350 1137 1351 docvec_ref_arena![arena, attributes, function] 1138 1352 } ··· 1176 1390 let header = match return_annotation { 1177 1391 None => header, 1178 1392 Some(return_annotation) => header 1179 - .append(arena, " -> ") 1393 + .append(arena, cache.space_right_arrow_space) 1180 1394 .append(arena, self.type_ast(arena, cache, return_annotation)), 1181 1395 }; 1182 1396 ··· 1218 1432 // todo to make it explicit it has an unimplemented callback. 1219 1433 if statement.is_use() && i == count - 1 { 1220 1434 documents.push(cache.line); 1221 - documents.push("todo".to_doc(arena)); 1435 + documents.push(cache.todo); 1222 1436 } 1223 1437 } 1224 1438 ··· 1251 1465 let _ = self.pop_empty_lines(pattern.location().end); 1252 1466 1253 1467 let (keyword, message) = match kind { 1254 - AssignmentKind::Let | AssignmentKind::Generated => ("let ", None), 1255 - AssignmentKind::Assert { message, .. } => ("let assert ", message.as_ref()), 1468 + AssignmentKind::Let | AssignmentKind::Generated => (cache.let_space, None), 1469 + AssignmentKind::Assert { message, .. } => (cache.let_assert_space, message.as_ref()), 1256 1470 }; 1257 1471 1258 1472 let pattern = self.pattern(arena, cache, pattern); 1259 1473 1260 1474 let annotation = annotation.as_ref().map(|annotation| { 1261 - ": ".to_doc(arena) 1475 + cache 1476 + .colon_space 1262 1477 .append(arena, self.type_ast(arena, cache, annotation)) 1263 1478 }); 1264 1479 1265 1480 let doc = keyword 1266 1481 .to_doc(arena) 1267 1482 .append(arena, pattern.append(arena, annotation).group(arena)) 1268 - .append(arena, " =") 1483 + .append(arena, cache.space_equal) 1269 1484 .append(arena, self.assigned_value(arena, cache, value)); 1270 1485 1271 1486 commented( ··· 1288 1503 UntypedExpr::Panic { message, .. } => self.append_as_message_expression( 1289 1504 arena, 1290 1505 cache, 1291 - "panic".to_doc(arena), 1506 + cache.panic, 1292 1507 PrecedingAs::Keyword, 1293 1508 message.as_deref(), 1294 1509 ), ··· 1296 1511 UntypedExpr::Todo { message, .. } => self.append_as_message_expression( 1297 1512 arena, 1298 1513 cache, 1299 - "todo".to_doc(arena), 1514 + cache.todo, 1300 1515 PrecedingAs::Keyword, 1301 1516 message.as_deref(), 1302 1517 ), ··· 1324 1539 .. 1325 1540 } => self.block(arena, cache, location, statements, false), 1326 1541 1327 - UntypedExpr::Var { name, .. } if name == CAPTURE_VARIABLE => "_".to_doc(arena), 1542 + UntypedExpr::Var { name, .. } if name == CAPTURE_VARIABLE => cache.underscore, 1328 1543 1329 1544 UntypedExpr::Var { name, .. } => name.to_doc(arena), 1330 1545 ··· 1393 1608 label, container, .. 1394 1609 } => self 1395 1610 .expr(arena, cache, container) 1396 - .append(arena, ".") 1611 + .append(arena, cache.dot) 1397 1612 .append(arena, label.as_str()), 1398 1613 1399 1614 UntypedExpr::Tuple { elements, location } => { ··· 1435 1650 fn string( 1436 1651 &self, 1437 1652 arena: &'doc DocumentArena<'a, 'doc>, 1438 - _cache: &'doc FormatterCache<'a, 'doc>, 1653 + cache: &'doc FormatterCache<'a, 'doc>, 1439 1654 string: &'a EcoString, 1440 1655 ) -> Document<'a, 'doc> { 1441 - let doc = string.to_doc(arena).surround(arena, "\"", "\""); 1656 + let doc = string 1657 + .to_doc(arena) 1658 + .surround(arena, cache.double_quote, cache.double_quote); 1442 1659 if string.contains('\n') { 1443 1660 doc.force_break(arena) 1444 1661 } else { ··· 1454 1671 ) -> Document<'a, 'doc> { 1455 1672 let lines = string.split('\n').collect_vec(); 1456 1673 match lines.as_slice() { 1457 - [] | [_] => string.to_doc(arena).surround(arena, "\"", "\""), 1674 + [] | [_] => { 1675 + string 1676 + .to_doc(arena) 1677 + .surround(arena, cache.double_quote, cache.double_quote) 1678 + } 1458 1679 [first_line, lines @ ..] => { 1459 - let mut doc = docvec_ref_arena![arena, "\"", *first_line]; 1680 + let mut doc = docvec_ref_arena![arena, cache.double_quote, *first_line]; 1460 1681 for line in lines { 1461 1682 doc = doc 1462 1683 .append(arena, cache.line.set_nesting(arena, 0)) 1463 1684 .append(arena, line.to_doc(arena)) 1464 1685 } 1465 - doc.append(arena, "\"".to_doc(arena)).group(arena) 1686 + doc.append(arena, cache.double_quote).group(arena) 1466 1687 } 1467 1688 } 1468 1689 } ··· 1478 1699 let integer_part = parts.next().unwrap_or_default(); 1479 1700 let floating_part = parts.next().unwrap_or_default(); 1480 1701 let integer_doc = self.underscore_integer_string(arena, cache, integer_part); 1481 - let dot_doc = ".".to_doc(arena); 1482 - 1483 1702 // Split fp_part into a regular fractional and maybe a scientific part 1484 1703 let (fractional_part, scientific_part) = floating_part.split_at( 1485 1704 floating_part ··· 1497 1716 let float_doc = fractional_part.chars().collect::<EcoString>(); 1498 1717 1499 1718 integer_doc 1500 - .append(arena, dot_doc) 1719 + .append(arena, cache.dot) 1501 1720 .append(arena, float_doc) 1502 1721 .append(arena, scientific_part) 1503 1722 } ··· 1574 1793 } 1575 1794 1576 1795 let name = match module { 1577 - Some((module, _)) => module.to_doc(arena).append(arena, ".").append(arena, name), 1796 + Some((module, _)) => module 1797 + .to_doc(arena) 1798 + .append(arena, cache.dot) 1799 + .append(arena, name), 1578 1800 None => name.to_doc(arena), 1579 1801 }; 1580 1802 1581 1803 if arguments.is_empty() && spread.is_some() { 1582 - name.append(arena, "(..)") 1804 + name.append(arena, cache.open_paren_dot_dot_close_paren) 1583 1805 } else if arguments.is_empty() { 1584 1806 name 1585 1807 } else if spread.is_some() { ··· 1595 1817 } else { 1596 1818 match arguments { 1597 1819 [argument] if is_breakable(&argument.value) => name 1598 - .append(arena, "(") 1820 + .append(arena, cache.open_paren) 1599 1821 .append(arena, self.pattern_call_arg(arena, cache, argument)) 1600 - .append(arena, ")") 1822 + .append(arena, cache.close_paren) 1601 1823 .group(arena), 1602 1824 1603 1825 _ => { ··· 1674 1896 // that is all comments that are inside "#(" and ")", if there's 1675 1897 // any comment we want to put it inside the empty tuple! 1676 1898 return match printed_comments(arena, cache, self.pop_comments(location.end), false) { 1677 - None => "#()".to_doc(arena), 1678 - Some(comments) => "#(" 1679 - .to_doc(arena) 1899 + None => cache.empty_tuple, 1900 + Some(comments) => cache 1901 + .open_tuple 1680 1902 .append(arena, cache.empty_break.nest(arena, INDENT)) 1681 1903 .append(arena, comments) 1682 1904 .append(arena, cache.empty_break) 1683 - .append(arena, ")") 1905 + .append(arena, cache.close_paren) 1684 1906 // vvv We want to make sure the comments are on a separate 1685 1907 // line from the opening and closing parentheses so we 1686 1908 // force the breaks to be split on newlines. ··· 1691 1913 self.append_inlinable_wrapped_arguments( 1692 1914 arena, 1693 1915 cache, 1694 - "#".to_doc(arena), 1916 + cache.hashtag, 1695 1917 elements, 1696 1918 location, 1697 1919 |expression| { ··· 1776 1998 subjects 1777 1999 .iter() 1778 2000 .map(|subject| self.expr(arena, cache, subject).group(arena)), 1779 - arena.break_(",", ", "), 2001 + cache.comma_break, 1780 2002 ), 1781 2003 ) 1782 2004 .nest(arena, INDENT) 1783 2005 .append(arena, cache.breakable_space) 1784 - .append(arena, "{") 2006 + .append(arena, cache.open_curly) 1785 2007 .next_break_fits(arena, NextBreakFitsMode::Disabled) 1786 2008 .group(arena); 1787 2009 ··· 1798 2020 // Otherwise those would be moved out of the case expression. 1799 2021 let comments = self.pop_comments(location.end); 1800 2022 let closing_bracket = match printed_comments(arena, cache, comments, false) { 1801 - None => docvec_ref_arena![arena, cache.line, "}"], 2023 + None => docvec_ref_arena![arena, cache.line, cache.close_curly], 1802 2024 Some(comment) => docvec_ref_arena![arena, cache.line, comment] 1803 2025 .nest(arena, INDENT) 1804 2026 .append(arena, cache.line) 1805 - .append(arena, "}"), 2027 + .append(arena, cache.close_curly), 1806 2028 }; 1807 2029 1808 2030 subjects_doc ··· 1850 2072 commented( 1851 2073 arena, 1852 2074 cache, 1853 - "..".to_doc(arena) 2075 + cache 2076 + .dot_dot 1854 2077 .append(arena, this.expr(arena, cache, &record.base)), 1855 2078 comments, 1856 2079 ) ··· 1872 2095 let constructor_doc = match module { 1873 2096 Some((m, _)) => m 1874 2097 .to_doc(arena) 1875 - .append(arena, ".") 2098 + .append(arena, cache.dot) 1876 2099 .append(arena, name.as_str()), 1877 2100 None => name.to_doc(arena), 1878 2101 }; ··· 1887 2110 RecordUpdatePiece::Argument(argument) => { 1888 2111 let comments = self.pop_comments(argument.location.start); 1889 2112 let doc = match argument { 1890 - _ if argument.uses_label_shorthand() => { 1891 - argument.label.as_str().to_doc(arena).append(arena, ":") 1892 - } 2113 + _ if argument.uses_label_shorthand() => argument 2114 + .label 2115 + .as_str() 2116 + .to_doc(arena) 2117 + .append(arena, cache.colon), 1893 2118 _ => argument 1894 2119 .label 1895 2120 .as_str() 1896 2121 .to_doc(arena) 1897 - .append(arena, ": ") 2122 + .append(arena, cache.colon_space) 1898 2123 .append(arena, self.const_expr(arena, cache, &argument.value)) 1899 2124 .group(arena), 1900 2125 }; ··· 1905 2130 commented( 1906 2131 arena, 1907 2132 cache, 1908 - "..".to_doc(arena) 2133 + cache 2134 + .dot_dot 1909 2135 .append(arena, self.const_expr(arena, cache, &record.base)), 1910 2136 comments, 1911 2137 ) ··· 1930 2156 let left_side = self.bin_op_side(arena, cache, name, left, nest_steps); 1931 2157 1932 2158 let comments = self.pop_comments(right.start_byte_index()); 1933 - let name_doc = cache 1934 - .breakable_space 1935 - .append(arena, commented(arena, cache, name.to_doc(arena), comments)); 2159 + let name_doc = cache.breakable_space.append( 2160 + arena, 2161 + commented(arena, cache, binop(*name, cache), comments), 2162 + ); 1936 2163 1937 2164 let right_side = self.bin_op_side(arena, cache, name, right, nest_steps); 1938 2165 ··· 1945 2172 name_doc 1946 2173 }, 1947 2174 ) 1948 - .append(arena, " ") 2175 + .append(arena, cache.space) 1949 2176 .append(arena, right_side) 1950 2177 } 1951 2178 ··· 2091 2318 } else { 2092 2319 cache.line 2093 2320 }; 2094 - let pipe = space.append( 2095 - arena, 2096 - commented(arena, cache, "|> ".to_doc(arena), comments), 2097 - ); 2321 + let pipe = space.append(arena, commented(arena, cache, cache.pipe_space, comments)); 2098 2322 let pipe = if nest_pipe { 2099 2323 pipe.nest(arena, INDENT) 2100 2324 } else { ··· 2238 2462 let argument = match label { 2239 2463 Some((_, label)) => label 2240 2464 .to_doc(arena) 2241 - .append(arena, ": ") 2465 + .append(arena, cache.colon_space) 2242 2466 .append(arena, self.type_ast(arena, cache, ast)), 2243 2467 None => self.type_ast(arena, cache, ast), 2244 2468 }; ··· 2304 2528 .to_doc(arena); 2305 2529 2306 2530 let doc = attributes 2307 - .append(arena, pub_(arena, cache, *publicity)) 2308 - .append(arena, if *opaque { "opaque type " } else { "type " }) 2531 + .append(arena, pub_(cache, *publicity)) 2532 + .append( 2533 + arena, 2534 + if *opaque { 2535 + cache.opaque_type_space 2536 + } else { 2537 + cache.type_space 2538 + }, 2539 + ) 2309 2540 .append( 2310 2541 arena, 2311 2542 if parameters.is_empty() { ··· 2331 2562 if constructors.is_empty() { 2332 2563 return doc; 2333 2564 } 2334 - let doc = doc.append(arena, " {"); 2565 + let doc = doc.append(arena, cache.space_open_curly); 2335 2566 2336 2567 let inner = arena.concat(constructors.iter().map(|c| { 2337 2568 if self.pop_empty_lines(c.location.start) { ··· 2352 2583 2353 2584 doc.append(arena, inner) 2354 2585 .append(arena, cache.line) 2355 - .append(arena, "}") 2586 + .append(arena, cache.close_curly) 2356 2587 } 2357 2588 2358 2589 fn call_arg( ··· 2387 2618 CallArgFormatting::Unlabelled(value) => format_value(self, value), 2388 2619 CallArgFormatting::ShorthandLabelled(label) => { 2389 2620 let comments = self.pop_comments(argument.location.start); 2390 - let label = label.as_ref().to_doc(arena).append(arena, ":"); 2621 + let label = label.as_ref().to_doc(arena).append(arena, cache.colon); 2391 2622 commented(arena, cache, label, comments) 2392 2623 } 2393 2624 CallArgFormatting::Labelled(label, value) => { 2394 2625 let comments = self.pop_comments(argument.location.start); 2395 - let label = label.as_ref().to_doc(arena).append(arena, ": "); 2626 + let label = label 2627 + .as_ref() 2628 + .to_doc(arena) 2629 + .append(arena, cache.colon_space); 2396 2630 let value = format_value(self, value); 2397 2631 commented(arena, cache, label, comments).append(arena, value) 2398 2632 } ··· 2411 2645 _ if argument.uses_label_shorthand() => commented( 2412 2646 arena, 2413 2647 cache, 2414 - argument.label.as_str().to_doc(arena).append(arena, ":"), 2648 + argument 2649 + .label 2650 + .as_str() 2651 + .to_doc(arena) 2652 + .append(arena, cache.colon), 2415 2653 comments, 2416 2654 ), 2417 2655 // Labelled argument. ··· 2420 2658 .label 2421 2659 .as_str() 2422 2660 .to_doc(arena) 2423 - .append(arena, ": ") 2661 + .append(arena, cache.colon_space) 2424 2662 .append(arena, self.expr(arena, cache, &argument.value)) 2425 2663 .group(arena); 2426 2664 ··· 2461 2699 } else { 2462 2700 self.expr(arena, cache, tuple) 2463 2701 } 2464 - .append(arena, ".") 2702 + .append(arena, cache.dot) 2465 2703 .append(arena, index) 2466 2704 } 2467 2705 ··· 2573 2811 Some(guard) => self 2574 2812 .alternative_patterns(arena, cache, clause) 2575 2813 .append(arena, cache.breakable_space.nest(arena, INDENT)) 2576 - .append(arena, "if ") 2814 + .append(arena, cache.if_space) 2577 2815 .append( 2578 2816 arena, 2579 2817 self.clause_guard(arena, cache, guard) ··· 2605 2843 cache.space 2606 2844 }; 2607 2845 2608 - let clause_doc = docvec_ref_arena![arena, clause_doc, arrow_break, "->"] 2846 + let clause_doc = docvec_ref_arena![arena, clause_doc, arrow_break, cache.right_arrow] 2609 2847 .group(arena) 2610 2848 .append(arena, self.case_clause_value(arena, cache, &clause.then)) 2611 2849 .group(arena); ··· 2651 2889 cache 2652 2890 .breakable_space 2653 2891 .nest(arena, INDENT) 2654 - .append(arena, "| ") 2892 + .append(arena, cache.vertical_bar_space) 2655 2893 } else { 2656 - cache.breakable_space.append(arena, "| ") 2894 + cache 2895 + .breakable_space 2896 + .append(arena, cache.vertical_bar_space) 2657 2897 }; 2658 2898 2659 2899 let alternative_patterns = std::iter::once(&clause.pattern) ··· 2691 2931 // going to be nested) and make the subjects into a group to 2692 2932 // make sure the formatter tries to keep them on a single line. 2693 2933 arena 2694 - .join(pattern_docs, arena.break_(",", ", ").nest(arena, INDENT)) 2934 + .join(pattern_docs, cache.comma_break.nest(arena, INDENT)) 2695 2935 .group(arena) 2696 2936 }); 2697 2937 arena.join(alternative_patterns, alternatives_separator) ··· 2714 2954 None => { 2715 2955 let comments = self.pop_comments(location.end); 2716 2956 match printed_comments(arena, cache, comments, false) { 2717 - None => "[]".to_doc(arena), 2718 - Some(comments) => "[" 2719 - .to_doc(arena) 2957 + None => cache.open_close_square, 2958 + Some(comments) => cache 2959 + .open_square 2720 2960 .append(arena, cache.empty_break.nest(arena, INDENT)) 2721 2961 .append(arena, comments) 2722 2962 .append(arena, cache.empty_break) 2723 - .append(arena, "]") 2963 + .append(arena, cache.close_square) 2724 2964 // vvv We want to make sure the comments are on a separate 2725 2965 // line from the opening and closing brackets so we 2726 2966 // force the breaks to be split on newlines. ··· 2738 2978 ); 2739 2979 2740 2980 let comma = match list_packing { 2741 - ItemsPacking::FitMultiplePerLine => arena.flex_break(",", ", "), 2742 - ItemsPacking::FitOnePerLine | ItemsPacking::BreakOnePerLine => arena.break_(",", ", "), 2981 + ItemsPacking::FitMultiplePerLine => cache.flex_comma, 2982 + ItemsPacking::FitOnePerLine | ItemsPacking::BreakOnePerLine => cache.comma_break, 2743 2983 }; 2744 2984 2745 2985 let list_size = elements.len() ··· 2773 3013 } 2774 3014 elements_doc = elements_doc.next_break_fits(arena, NextBreakFitsMode::Disabled); 2775 3015 2776 - let doc = arena.break_("[", "[").append(arena, elements_doc); 3016 + let doc = cache.open_square_break.append(arena, elements_doc); 2777 3017 // We need to keep the last break aside and do not add it immediately 2778 3018 // because in case there's a final comment before the closing square 2779 3019 // bracket we want to add indentation (to just that break). Otherwise, 2780 3020 // the final comment would be less indented than list's elements. 2781 3021 let (doc, last_break) = match tail { 2782 - None => (doc.nest(arena, INDENT), arena.break_(",", "")), 3022 + None => (doc.nest(arena, INDENT), cache.trailing_comma_break), 2783 3023 2784 3024 Some(tail) => { 2785 3025 let comments = self.pop_comments(tail.location().start); 2786 3026 let tail = commented( 2787 3027 arena, 2788 3028 cache, 2789 - docvec_ref_arena![arena, "..", self.expr(arena, cache, tail)], 3029 + docvec_ref_arena![arena, cache.dot_dot, self.expr(arena, cache, tail)], 2790 3030 comments, 2791 3031 ); 2792 3032 ( 2793 - doc.append(arena, arena.break_(",", ", ")) 3033 + doc.append(arena, cache.comma_break) 2794 3034 .append(arena, tail) 2795 3035 .nest(arena, INDENT), 2796 3036 cache.empty_break, ··· 2805 3045 // Otherwise those would be moved out of the list. 2806 3046 let comments = self.pop_comments(location.end); 2807 3047 let doc = match printed_comments(arena, cache, comments, false) { 2808 - None => doc.append(arena, last_break).append(arena, "]"), 3048 + None => doc 3049 + .append(arena, last_break) 3050 + .append(arena, cache.close_square), 2809 3051 Some(comment) => doc 2810 3052 .append(arena, last_break.nest(arena, INDENT)) 2811 3053 // ^ See how here we're adding the missing indentation to the ··· 2813 3055 // list's items. 2814 3056 .append(arena, comment) 2815 3057 .append(arena, cache.line) 2816 - .append(arena, "]") 3058 + .append(arena, cache.close_square) 2817 3059 .force_break(arena), 2818 3060 }; 2819 3061 ··· 2996 3238 name.to_doc(arena) 2997 3239 } else { 2998 3240 self.pattern(arena, cache, pattern) 2999 - .append(arena, " as ") 3241 + .append(arena, cache.space_as_space) 3000 3242 .append(arena, name.as_str()) 3001 3243 } 3002 3244 } ··· 3063 3305 }; 3064 3306 match left_assign { 3065 3307 Some((name, _)) => { 3066 - docvec_ref_arena![arena, left, " as ", name, " <> ", right] 3308 + docvec_ref_arena![ 3309 + arena, 3310 + left, 3311 + cache.space_as_space, 3312 + name, 3313 + cache.space_concat_space, 3314 + right 3315 + ] 3067 3316 } 3068 - None => docvec_ref_arena![arena, left, " <> ", right], 3317 + None => docvec_ref_arena![arena, left, cache.space_concat_space, right], 3069 3318 } 3070 3319 } 3071 3320 ··· 3090 3339 .. 3091 3340 } => { 3092 3341 let operator = match operator { 3093 - IntOperator::Add => " + ", 3094 - IntOperator::Subtract => " - ", 3095 - IntOperator::Multiply => " * ", 3096 - IntOperator::Divide => " / ", 3097 - IntOperator::Remainder => " % ", 3342 + IntOperator::Add => cache.space_plus_space, 3343 + IntOperator::Subtract => cache.space_minus_space, 3344 + IntOperator::Multiply => cache.space_times_space, 3345 + IntOperator::Divide => cache.space_slash_space, 3346 + IntOperator::Remainder => cache.space_module_space, 3098 3347 }; 3099 3348 3100 3349 docvec_ref_arena![ ··· 3104 3353 self.bit_array_size(arena, cache, right) 3105 3354 ] 3106 3355 } 3107 - BitArraySize::Block { inner, .. } => self 3108 - .bit_array_size(arena, cache, inner) 3109 - .surround(arena, "{ ", " }"), 3356 + BitArraySize::Block { inner, .. } => self.bit_array_size(arena, cache, inner).surround( 3357 + arena, 3358 + cache.open_curly_space, 3359 + cache.space_close_curly, 3360 + ), 3110 3361 } 3111 3362 } 3112 3363 ··· 3120 3371 if elements.is_empty() { 3121 3372 return match tail { 3122 3373 Some(tail) => self.pattern(arena, cache, &tail.pattern), 3123 - None => "[]".to_doc(arena), 3374 + None => cache.open_close_square, 3124 3375 }; 3125 3376 } 3126 3377 let elements = arena.join( 3127 3378 elements 3128 3379 .iter() 3129 3380 .map(|element| self.pattern(arena, cache, element)), 3130 - arena.break_(",", ", "), 3381 + cache.comma_break, 3131 3382 ); 3132 - let doc = arena.break_("[", "[").append(arena, elements); 3383 + let doc = cache.open_square_break.append(arena, elements); 3133 3384 match tail { 3134 - None => doc.nest(arena, INDENT).append(arena, arena.break_(",", "")), 3385 + None => doc 3386 + .nest(arena, INDENT) 3387 + .append(arena, cache.trailing_comma_break), 3135 3388 3136 3389 Some(tail) => { 3137 3390 let tail = &tail.pattern; 3138 3391 let comments = self.pop_comments(tail.location().start); 3139 3392 let tail = if tail.is_discard() { 3140 - "..".to_doc(arena) 3393 + cache.dot_dot 3141 3394 } else { 3142 - docvec_ref_arena![arena, "..", self.pattern(arena, cache, tail)] 3395 + docvec_ref_arena![arena, cache.dot_dot, self.pattern(arena, cache, tail)] 3143 3396 }; 3144 3397 let tail = commented(arena, cache, tail, comments); 3145 - doc.append(arena, arena.break_(",", ", ")) 3398 + doc.append(arena, cache.comma_break) 3146 3399 .append(arena, tail) 3147 3400 .nest(arena, INDENT) 3148 3401 .append(arena, cache.empty_break) ··· 3177 3430 ) -> Document<'a, 'doc> { 3178 3431 self.clause_guard_bin_op_side(arena, cache, name, left, left.precedence()) 3179 3432 .append(arena, cache.breakable_space) 3180 - .append(arena, name.to_doc(arena)) 3433 + .append(arena, binop(*name, cache)) 3181 3434 .append(arena, cache.space) 3182 3435 .append( 3183 3436 arena, ··· 3241 3494 3242 3495 ClauseGuard::TupleIndex { tuple, index, .. } => self 3243 3496 .clause_guard(arena, cache, tuple) 3244 - .append(arena, ".") 3497 + .append(arena, cache.dot) 3245 3498 .append(arena, *index) 3246 3499 .to_doc(arena), 3247 3500 ··· 3249 3502 container, label, .. 3250 3503 } => self 3251 3504 .clause_guard(arena, cache, container) 3252 - .append(arena, ".") 3505 + .append(arena, cache.dot) 3253 3506 .append(arena, label) 3254 3507 .to_doc(arena), 3255 3508 ··· 3257 3510 module_name, label, .. 3258 3511 } => module_name 3259 3512 .to_doc(arena) 3260 - .append(arena, ".") 3513 + .append(arena, cache.dot) 3261 3514 .append(arena, label) 3262 3515 .to_doc(arena), 3263 3516 3264 3517 ClauseGuard::Constant(constant) => self.const_expr(arena, cache, constant), 3265 3518 3266 3519 ClauseGuard::Not { expression, .. } => { 3267 - docvec_ref_arena![arena, "!", self.clause_guard(arena, cache, expression)] 3520 + docvec_ref_arena![ 3521 + arena, 3522 + cache.exclamation_mark, 3523 + self.clause_guard(arena, cache, expression) 3524 + ] 3268 3525 } 3269 3526 3270 3527 ClauseGuard::Block { value, .. } => { ··· 3298 3555 UntypedExpr::NegateBool { value, .. } => self.expr(arena, cache, value), 3299 3556 UntypedExpr::BinOp { .. } => { 3300 3557 let doc = self.expr(arena, cache, expression); 3301 - "!".to_doc(arena) 3558 + cache 3559 + .exclamation_mark 3302 3560 .append(arena, wrap_block(arena, cache, doc)) 3303 3561 } 3304 3562 UntypedExpr::Int { .. } ··· 3320 3578 | UntypedExpr::BitArray { .. } 3321 3579 | UntypedExpr::RecordUpdate { .. } 3322 3580 | UntypedExpr::NegateInt { .. } => { 3323 - docvec_ref_arena![arena, "!", self.expr(arena, cache, expression)] 3581 + docvec_ref_arena![ 3582 + arena, 3583 + cache.exclamation_mark, 3584 + self.expr(arena, cache, expression) 3585 + ] 3324 3586 } 3325 3587 } 3326 3588 } ··· 3336 3598 UntypedExpr::Int { value, .. } if value.starts_with('-') => { 3337 3599 self.int(arena, cache, &value[1..]) 3338 3600 } 3339 - UntypedExpr::BinOp { .. } => "- " 3340 - .to_doc(arena) 3601 + UntypedExpr::BinOp { .. } => cache 3602 + .minus_space 3341 3603 .append(arena, self.expr(arena, cache, expression)), 3342 3604 3343 3605 UntypedExpr::Int { .. } ··· 3359 3621 | UntypedExpr::BitArray { .. } 3360 3622 | UntypedExpr::RecordUpdate { .. } 3361 3623 | UntypedExpr::NegateBool { .. } => { 3362 - docvec_ref_arena![arena, "-", self.expr(arena, cache, expression)] 3624 + docvec_ref_arena![arena, cache.sub_int, self.expr(arena, cache, expression)] 3363 3625 } 3364 3626 } 3365 3627 } ··· 3385 3647 .group(arena); 3386 3648 3387 3649 let doc = if use_.assignments.is_empty() { 3388 - docvec_ref_arena![arena, "use <-", call] 3650 + docvec_ref_arena![arena, cache.use_and_arrow, call] 3389 3651 } else { 3390 3652 let assignments = use_.assignments.iter().map(|use_assignment| { 3391 3653 let pattern = self.pattern(arena, cache, &use_assignment.pattern); 3392 3654 let annotation = use_assignment.annotation.as_ref().map(|annotation| { 3393 - ": ".to_doc(arena) 3655 + cache 3656 + .colon_space 3394 3657 .append(arena, self.type_ast(arena, cache, annotation)) 3395 3658 }); 3396 3659 3397 3660 pattern.append(arena, annotation).group(arena) 3398 3661 }); 3399 - let assignments = Itertools::intersperse(assignments, arena.break_(",", ", ")); 3400 - let left = ["use".to_doc(arena), cache.breakable_space] 3662 + let assignments = Itertools::intersperse(assignments, cache.comma_break); 3663 + let left = [cache.use_, cache.breakable_space] 3401 3664 .into_iter() 3402 3665 .chain(assignments); 3403 3666 let left = arena ··· 3405 3668 .nest(arena, INDENT) 3406 3669 .append(arena, cache.breakable_space) 3407 3670 .group(arena); 3408 - docvec_ref_arena![arena, left, "<-", call].group(arena) 3671 + docvec_ref_arena![arena, left, cache.left_arrow, call].group(arena) 3409 3672 }; 3410 3673 3411 3674 commented(arena, cache, doc, comments) ··· 3435 3698 commented( 3436 3699 arena, 3437 3700 cache, 3438 - docvec_ref_arena![arena, "assert ", doc], 3701 + docvec_ref_arena![arena, cache.assert_space, doc], 3439 3702 comments, 3440 3703 ) 3441 3704 } ··· 3458 3721 // any comment we want to put it inside the empty bit array! 3459 3722 // Refer to the `list` function for a similar procedure. 3460 3723 return match comments_doc { 3461 - None => "<<>>".to_doc(arena), 3462 - Some(comments) => "<<" 3463 - .to_doc(arena) 3724 + None => cache.empty_bit_array, 3725 + Some(comments) => cache 3726 + .open_bit_array 3464 3727 .append(arena, cache.empty_break.nest(arena, INDENT)) 3465 3728 .append(arena, comments) 3466 3729 .append(arena, cache.empty_break) 3467 - .append(arena, ">>") 3730 + .append(arena, cache.close_bit_array) 3468 3731 // vvv We want to make sure the comments are on a separate 3469 3732 // line from the opening and closing angle brackets so 3470 3733 // we force the breaks to be split on newlines. ··· 3473 3736 } 3474 3737 3475 3738 let comma = match packing { 3476 - ItemsPacking::FitMultiplePerLine => arena.flex_break(",", ", "), 3477 - ItemsPacking::FitOnePerLine | ItemsPacking::BreakOnePerLine => arena.break_(",", ", "), 3739 + ItemsPacking::FitMultiplePerLine => cache.flex_comma, 3740 + ItemsPacking::FitOnePerLine | ItemsPacking::BreakOnePerLine => cache.comma_break, 3478 3741 }; 3479 3742 3480 - let last_break = arena.break_(",", ""); 3481 - let doc = arena 3482 - .break_("<<", "<<") 3743 + let last_break = cache.trailing_comma_break; 3744 + let doc = cache 3745 + .open_bit_array_break 3483 3746 .append(arena, arena.join(segments, comma)) 3484 3747 .nest(arena, INDENT); 3485 3748 3486 3749 let doc = match comments_doc { 3487 - None => doc.append(arena, last_break).append(arena, ">>"), 3750 + None => doc 3751 + .append(arena, last_break) 3752 + .append(arena, cache.close_bit_array), 3488 3753 Some(comments) => doc 3489 3754 .append(arena, last_break.nest(arena, INDENT)) 3490 3755 // ^ Notice how in this case we nest the final break before ··· 3492 3757 // indented as the bit array items. 3493 3758 .append(arena, comments.nest(arena, INDENT)) 3494 3759 .append(arena, cache.line) 3495 - .append(arena, ">>") 3760 + .append(arena, cache.close_bit_array) 3496 3761 .force_break(arena), 3497 3762 }; 3498 3763 ··· 3569 3834 let block_doc = match trailing_comments { 3570 3835 Some(trailing_comments_doc) => docvec_ref_arena![ 3571 3836 arena, 3572 - "{", 3837 + cache.open_curly, 3573 3838 statements_doc, 3574 3839 cache.line.nest(arena, INDENT), 3575 3840 trailing_comments_doc.nest(arena, INDENT), 3576 3841 cache.line, 3577 - "}" 3842 + cache.close_curly 3578 3843 ] 3579 3844 .force_break(arena), 3580 - None => docvec_ref_arena![arena, "{", statements_doc, cache.breakable_space, "}"], 3845 + None => docvec_ref_arena![ 3846 + arena, 3847 + cache.open_curly, 3848 + statements_doc, 3849 + cache.breakable_space, 3850 + cache.close_curly 3851 + ], 3581 3852 }; 3582 3853 3583 3854 if force_breaks { ··· 3599 3870 { 3600 3871 let mut arguments = arguments.into_iter().peekable(); 3601 3872 if arguments.peek().is_none() { 3602 - return "()".to_doc(arena); 3873 + return cache.open_close_paren; 3603 3874 } 3604 3875 3605 - let arguments_doc = arena 3606 - .break_("", "") 3607 - .append(arena, arena.join(arguments, arena.break_(",", ", "))) 3876 + let arguments_doc = cache 3877 + .empty_break 3878 + .append(arena, arena.join(arguments, cache.comma_break)) 3608 3879 .nest_if_broken(arena, INDENT); 3609 3880 3610 3881 // We get all remaining comments that come before the call's closing ··· 3614 3885 // Otherwise those would be moved out of the call. 3615 3886 let comments = self.pop_comments(location.end); 3616 3887 let closing_parens = match printed_comments(arena, cache, comments, false) { 3617 - None => docvec_ref_arena![arena, arena.break_(",", ""), ")"], 3888 + None => docvec_ref_arena![arena, cache.trailing_comma_break, cache.close_paren], 3618 3889 Some(comment) => docvec_ref_arena![ 3619 3890 arena, 3620 - arena.break_(",", "").nest(arena, INDENT), 3891 + cache.trailing_comma_break.nest(arena, INDENT), 3621 3892 comment, 3622 3893 cache.line, 3623 - ")" 3894 + cache.close_paren 3624 3895 ] 3625 3896 .force_break(arena), 3626 3897 }; 3627 3898 3628 - "(".to_doc(arena) 3899 + cache 3900 + .open_paren 3629 3901 .append(arena, arguments_doc) 3630 3902 .append(arena, closing_parens) 3631 3903 .group(arena) ··· 3645 3917 if arguments.peek().is_none() { 3646 3918 let comments = self.pop_comments(comments_limit); 3647 3919 return match printed_comments(arena, cache, comments, false) { 3648 - Some(comments) => "(" 3920 + Some(comments) => cache 3921 + .open_paren 3649 3922 .to_doc(arena) 3650 3923 .append(arena, cache.empty_break) 3651 3924 .append(arena, comments) 3652 3925 .nest_if_broken(arena, INDENT) 3653 3926 .force_break(arena) 3654 3927 .append(arena, cache.empty_break) 3655 - .append(arena, ")"), 3656 - None => "()".to_doc(arena), 3928 + .append(arena, cache.close_paren), 3929 + None => cache.open_close_paren, 3657 3930 }; 3658 3931 } 3659 - let doc = arena 3660 - .break_("(", "(") 3661 - .append(arena, arena.join(arguments, arena.break_(",", ", "))); 3932 + let doc = cache 3933 + .open_paren_break 3934 + .append(arena, arena.join(arguments, cache.comma_break)); 3662 3935 3663 3936 // Include trailing comments if there are any 3664 3937 let comments = self.pop_comments(comments_limit); 3665 3938 match printed_comments(arena, cache, comments, false) { 3666 3939 Some(comments) => doc 3667 - .append(arena, arena.break_(",", "")) 3940 + .append(arena, cache.trailing_comma_break) 3668 3941 .append(arena, comments) 3669 3942 .nest_if_broken(arena, INDENT) 3670 3943 .force_break(arena) 3671 3944 .append(arena, cache.empty_break) 3672 - .append(arena, ")"), 3945 + .append(arena, cache.close_paren), 3673 3946 None => doc 3674 3947 .nest_if_broken(arena, INDENT) 3675 - .append(arena, arena.break_(",", "")) 3676 - .append(arena, ")"), 3948 + .append(arena, cache.trailing_comma_break) 3949 + .append(arena, cache.close_paren), 3677 3950 } 3678 3951 } 3679 3952 ··· 3691 3964 if arguments.peek().is_none() { 3692 3965 return self.wrap_arguments(arena, cache, arguments, comments_limit); 3693 3966 } 3694 - let doc = arena 3695 - .break_("(", "(") 3696 - .append(arena, arena.join(arguments, arena.break_(",", ", "))) 3697 - .append(arena, arena.break_(",", ", ")) 3698 - .append(arena, ".."); 3967 + let doc = cache 3968 + .open_paren_break 3969 + .append(arena, arena.join(arguments, cache.comma_break)) 3970 + .append(arena, cache.comma_break) 3971 + .append(arena, cache.dot_dot); 3699 3972 3700 3973 // Include trailing comments if there are any 3701 3974 let comments = self.pop_comments(comments_limit); 3702 3975 match printed_comments(arena, cache, comments, false) { 3703 3976 Some(comments) => doc 3704 - .append(arena, arena.break_(",", "")) 3977 + .append(arena, cache.trailing_comma_break) 3705 3978 .append(arena, comments) 3706 3979 .nest_if_broken(arena, INDENT) 3707 3980 .force_break(arena) 3708 3981 .append(arena, cache.empty_break) 3709 - .append(arena, ")"), 3982 + .append(arena, cache.close_paren), 3710 3983 None => doc 3711 3984 .nest_if_broken(arena, INDENT) 3712 - .append(arena, arena.break_(",", "")) 3713 - .append(arena, ")"), 3985 + .append(arena, cache.trailing_comma_break) 3986 + .append(arena, cache.close_paren), 3714 3987 } 3715 3988 } 3716 3989 ··· 3750 4023 } 3751 4024 (_, None) => continue, 3752 4025 }; 3753 - doc.push("//".to_doc(arena).append(arena, EcoString::from(comment))); 4026 + doc.push(cache.comment.append(arena, EcoString::from(comment))); 3754 4027 match comments.peek() { 3755 4028 // Next line is a comment 3756 4029 Some((_, Some(_))) => doc.push(cache.line), ··· 3787 4060 let comments = printed_comments(arena, cache, comments, false); 3788 4061 3789 4062 let as_ = match preceding_as { 3790 - PrecedingAs::Keyword => " as".to_doc(arena), 4063 + PrecedingAs::Keyword => cache.space_as, 3791 4064 PrecedingAs::Expression => { 3792 - docvec_ref_arena![arena, cache.breakable_space, "as"].nest(arena, INDENT) 4065 + docvec_ref_arena![arena, cache.breakable_space, cache.as_].nest(arena, INDENT) 3793 4066 } 3794 4067 }; 3795 4068 ··· 3871 4144 Some(comments) => docvec_ref_arena![ 3872 4145 arena, 3873 4146 doc.group(arena), 3874 - " as", 4147 + cache.space_as, 3875 4148 docvec_ref_arena![ 3876 4149 arena, 3877 4150 cache.line, ··· 3887 4160 .const_expr(arena, cache, message) 3888 4161 .group(arena) 3889 4162 .nest(arena, INDENT); 3890 - docvec_ref_arena![arena, doc.group(arena), " as ", message] 4163 + docvec_ref_arena![arena, doc.group(arena), cache.space_as_space, message] 3891 4164 } 3892 4165 }; 3893 4166 ··· 3905 4178 return self.append_as_message_expression( 3906 4179 arena, 3907 4180 cache, 3908 - "echo".to_doc(arena), 4181 + cache.echo, 3909 4182 PrecedingAs::Keyword, 3910 4183 message.as_deref(), 3911 4184 ); ··· 3939 4212 PrecedingAs::Expression, 3940 4213 message.as_deref(), 3941 4214 ); 3942 - docvec_ref_arena![arena, "echo ", doc] 4215 + docvec_ref_arena![arena, cache.echo_space, doc] 3943 4216 } else { 3944 4217 docvec_ref_arena![ 3945 4218 arena, 3946 - "echo ", 4219 + cache.echo_space, 3947 4220 self.append_as_message_expression( 3948 4221 arena, 3949 4222 cache, ··· 4017 4290 } 4018 4291 } 4019 4292 4020 - impl<'a, 'doc> Documentable<'a, 'doc> for &'a BinOp { 4021 - fn to_doc(self, arena: &'doc DocumentArena<'a, 'doc>) -> Document<'a, 'doc> { 4022 - match self { 4023 - BinOp::And => "&&", 4024 - BinOp::Or => "||", 4025 - BinOp::LtInt => "<", 4026 - BinOp::LtEqInt => "<=", 4027 - BinOp::LtFloat => "<.", 4028 - BinOp::LtEqFloat => "<=.", 4029 - BinOp::Eq => "==", 4030 - BinOp::NotEq => "!=", 4031 - BinOp::GtEqInt => ">=", 4032 - BinOp::GtInt => ">", 4033 - BinOp::GtEqFloat => ">=.", 4034 - BinOp::GtFloat => ">.", 4035 - BinOp::AddInt => "+", 4036 - BinOp::AddFloat => "+.", 4037 - BinOp::SubInt => "-", 4038 - BinOp::SubFloat => "-.", 4039 - BinOp::MultInt => "*", 4040 - BinOp::MultFloat => "*.", 4041 - BinOp::DivInt => "/", 4042 - BinOp::DivFloat => "/.", 4043 - BinOp::RemainderInt => "%", 4044 - BinOp::Concatenate => "<>", 4045 - } 4046 - .to_doc(arena) 4293 + fn binop<'a, 'doc>(binop: BinOp, cache: &'doc FormatterCache<'a, 'doc>) -> Document<'a, 'doc> { 4294 + match binop { 4295 + BinOp::And => cache.and, 4296 + BinOp::Or => cache.or, 4297 + BinOp::LtInt => cache.lt_int, 4298 + BinOp::LtEqInt => cache.lt_eq_int, 4299 + BinOp::LtFloat => cache.lt_float, 4300 + BinOp::LtEqFloat => cache.lt_eq_float, 4301 + BinOp::Eq => cache.eq, 4302 + BinOp::NotEq => cache.not_eq, 4303 + BinOp::GtEqInt => cache.gt_eq_int, 4304 + BinOp::GtInt => cache.gt_int, 4305 + BinOp::GtEqFloat => cache.gt_eq_float, 4306 + BinOp::GtFloat => cache.gt_float, 4307 + BinOp::AddInt => cache.add_int, 4308 + BinOp::AddFloat => cache.add_float, 4309 + BinOp::SubInt => cache.sub_int, 4310 + BinOp::SubFloat => cache.sub_float, 4311 + BinOp::MultInt => cache.mult_int, 4312 + BinOp::MultFloat => cache.mult_float, 4313 + BinOp::DivInt => cache.div_int, 4314 + BinOp::DivFloat => cache.div_float, 4315 + BinOp::RemainderInt => cache.remainder_int, 4316 + BinOp::Concatenate => cache.concat, 4047 4317 } 4048 4318 } 4049 4319 ··· 4341 4611 cache: &'doc FormatterCache<'a, 'doc>, 4342 4612 doc: Document<'a, 'doc>, 4343 4613 ) -> Document<'a, 'doc> { 4344 - "{".to_doc(arena) 4614 + cache 4615 + .open_curly 4345 4616 .append(arena, cache.line.append(arena, doc).nest(arena, INDENT)) 4346 4617 .append(arena, cache.line) 4347 - .append(arena, "}") 4618 + .append(arena, cache.close_curly) 4348 4619 .force_break(arena) 4349 4620 } 4350 4621 ··· 4353 4624 cache: &'doc FormatterCache<'a, 'doc>, 4354 4625 doc: Document<'a, 'doc>, 4355 4626 ) -> Document<'a, 'doc> { 4356 - arena 4357 - .break_("{", "{ ") 4627 + cache 4628 + .open_curly_break 4358 4629 .append(arena, doc) 4359 4630 .nest(arena, INDENT) 4360 4631 .append(arena, cache.breakable_space) 4361 - .append(arena, "}") 4632 + .append(arena, cache.close_curly) 4362 4633 } 4363 4634 4364 4635 fn printed_comments<'a, 'doc>( ··· 4432 4703 match segment { 4433 4704 BitArraySegment { value, options, .. } if options.is_empty() => to_doc(value), 4434 4705 4435 - BitArraySegment { value, options, .. } => to_doc(value).append(arena, ":").append( 4706 + BitArraySegment { value, options, .. } => to_doc(value).append(arena, cache.colon).append( 4436 4707 arena, 4437 4708 arena.join( 4438 4709 options 4439 4710 .iter() 4440 4711 .map(|option| segment_option(arena, cache, option, &mut to_doc)), 4441 - "-".to_doc(arena), 4712 + cache.sub_int, 4442 4713 ), 4443 4714 ), 4444 4715 } ··· 4446 4717 4447 4718 fn segment_option<'a, 'doc, ToDoc, Value>( 4448 4719 arena: &'doc DocumentArena<'a, 'doc>, 4449 - _cache: &'doc FormatterCache<'a, 'doc>, 4720 + cache: &'doc FormatterCache<'a, 'doc>, 4450 4721 option: &'a BitArrayOption<Value>, 4451 4722 mut to_doc: ToDoc, 4452 4723 ) -> Document<'a, 'doc> ··· 4454 4725 ToDoc: FnMut(&'a Value) -> Document<'a, 'doc>, 4455 4726 { 4456 4727 match option { 4457 - BitArrayOption::Bytes { .. } => "bytes".to_doc(arena), 4458 - BitArrayOption::Bits { .. } => "bits".to_doc(arena), 4459 - BitArrayOption::Int { .. } => "int".to_doc(arena), 4460 - BitArrayOption::Float { .. } => "float".to_doc(arena), 4461 - BitArrayOption::Utf8 { .. } => "utf8".to_doc(arena), 4462 - BitArrayOption::Utf16 { .. } => "utf16".to_doc(arena), 4463 - BitArrayOption::Utf32 { .. } => "utf32".to_doc(arena), 4464 - BitArrayOption::Utf8Codepoint { .. } => "utf8_codepoint".to_doc(arena), 4465 - BitArrayOption::Utf16Codepoint { .. } => "utf16_codepoint".to_doc(arena), 4466 - BitArrayOption::Utf32Codepoint { .. } => "utf32_codepoint".to_doc(arena), 4467 - BitArrayOption::Signed { .. } => "signed".to_doc(arena), 4468 - BitArrayOption::Unsigned { .. } => "unsigned".to_doc(arena), 4469 - BitArrayOption::Big { .. } => "big".to_doc(arena), 4470 - BitArrayOption::Little { .. } => "little".to_doc(arena), 4471 - BitArrayOption::Native { .. } => "native".to_doc(arena), 4728 + BitArrayOption::Bytes { .. } => cache.bytes, 4729 + BitArrayOption::Bits { .. } => cache.bits, 4730 + BitArrayOption::Int { .. } => cache.int, 4731 + BitArrayOption::Float { .. } => cache.float, 4732 + BitArrayOption::Utf8 { .. } => cache.utf8, 4733 + BitArrayOption::Utf16 { .. } => cache.utf16, 4734 + BitArrayOption::Utf32 { .. } => cache.utf32, 4735 + BitArrayOption::Utf8Codepoint { .. } => cache.utf8_codepoint, 4736 + BitArrayOption::Utf16Codepoint { .. } => cache.utf16_codepoint, 4737 + BitArrayOption::Utf32Codepoint { .. } => cache.utf32_codepoint, 4738 + BitArrayOption::Signed { .. } => cache.signed, 4739 + BitArrayOption::Unsigned { .. } => cache.unsigned, 4740 + BitArrayOption::Big { .. } => cache.big, 4741 + BitArrayOption::Little { .. } => cache.little, 4742 + BitArrayOption::Native { .. } => cache.native, 4472 4743 4473 4744 BitArrayOption::Size { 4474 4745 value, 4475 4746 short_form: false, 4476 4747 .. 4477 - } => "size" 4478 - .to_doc(arena) 4479 - .append(arena, "(") 4748 + } => cache 4749 + .size 4750 + .append(arena, cache.open_paren) 4480 4751 .append(arena, to_doc(value)) 4481 - .append(arena, ")"), 4752 + .append(arena, cache.close_paren), 4482 4753 4483 4754 BitArrayOption::Size { 4484 4755 value, ··· 4486 4757 .. 4487 4758 } => to_doc(value), 4488 4759 4489 - BitArrayOption::Unit { value, .. } => "unit" 4490 - .to_doc(arena) 4491 - .append(arena, "(") 4760 + BitArrayOption::Unit { value, .. } => cache 4761 + .value 4762 + .append(arena, cache.open_paren) 4492 4763 .append(arena, eco_format!("{value}")) 4493 - .append(arena, ")"), 4764 + .append(arena, cache.close_paren), 4494 4765 } 4495 4766 } 4496 4767 4497 4768 fn pub_<'a, 'doc>( 4498 - arena: &'doc DocumentArena<'a, 'doc>, 4499 4769 cache: &'doc FormatterCache<'a, 'doc>, 4500 4770 publicity: Publicity, 4501 4771 ) -> Document<'a, 'doc> { 4502 4772 match publicity { 4503 - Publicity::Public | Publicity::Internal { .. } => "pub ".to_doc(arena), 4773 + Publicity::Public | Publicity::Internal { .. } => cache.pub_space, 4504 4774 Publicity::Private => cache.nil, 4505 4775 } 4506 4776 }