| author | |
| committer | |
| log | 20554d32c0a9e8adeb311645797e0d6873f4bbc0 |
| tree | 1080a2c4700156e8b1283ddbadad64e1f4520063 |
| parent | bf8fafc37d4182196d108c773ae36c33a109d703 |
* start implementation of ast.Tree.firstToken and lastToken
* clarify some ast.Node doc comments
* reimplement renderToken5 files changed, 6134 insertions(+), 6093 deletions(-)
lib/std/zig/ast.zig+285-15| ... | ... | @@ -185,24 +185,293 @@ pub const Tree = struct { |
| 185 | 185 | } |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | /// Skips over comments. | |
| 189 | pub fn prevToken(self: *const Tree, token_index: TokenIndex) TokenIndex { | |
| 190 | const token_tags = self.tokens.items(.tag); | |
| 191 | var index = token_index - 1; | |
| 192 | while (token_tags[index] == .LineComment) { | |
| 193 | index -= 1; | |
| 188 | pub fn firstToken(tree: Tree, node: Node.Index) TokenIndex { | |
| 189 | const tags = tree.nodes.items(.tag); | |
| 190 | const datas = tree.nodes.items(.data); | |
| 191 | const main_tokens = tree.nodes.items(.main_token); | |
| 192 | switch (tags[node]) { | |
| 193 | .Root => return 0, | |
| 194 | ||
| 195 | .UsingNamespace, | |
| 196 | .TestDecl, | |
| 197 | .ErrDefer, | |
| 198 | .Defer, | |
| 199 | .BoolNot, | |
| 200 | .Negation, | |
| 201 | .BitNot, | |
| 202 | .NegationWrap, | |
| 203 | .AddressOf, | |
| 204 | .Try, | |
| 205 | .Await, | |
| 206 | .OptionalType, | |
| 207 | .ArrayInitDotTwo, | |
| 208 | .ArrayInitDot, | |
| 209 | .StructInitDotTwo, | |
| 210 | .StructInitDot, | |
| 211 | .Switch, | |
| 212 | .IfSimple, | |
| 213 | .IfSimpleOptional, | |
| 214 | .If, | |
| 215 | .IfOptional, | |
| 216 | .IfError, | |
| 217 | .Suspend, | |
| 218 | .Resume, | |
| 219 | .Continue, | |
| 220 | .Break, | |
| 221 | .Return, | |
| 222 | .AnyFrameType, | |
| 223 | .OneToken, | |
| 224 | .Identifier, | |
| 225 | .EnumLiteral, | |
| 226 | .MultilineStringLiteral, | |
| 227 | .GroupedExpression, | |
| 228 | .BuiltinCallTwo, | |
| 229 | .BuiltinCall, | |
| 230 | .ErrorSetDecl, | |
| 231 | .AnyType, | |
| 232 | .Comptime, | |
| 233 | .Nosuspend, | |
| 234 | .Block, | |
| 235 | .AsmSimple, | |
| 236 | .Asm, | |
| 237 | => return main_tokens[node], | |
| 238 | ||
| 239 | .Catch, | |
| 240 | .FieldAccess, | |
| 241 | .UnwrapOptional, | |
| 242 | .EqualEqual, | |
| 243 | .BangEqual, | |
| 244 | .LessThan, | |
| 245 | .GreaterThan, | |
| 246 | .LessOrEqual, | |
| 247 | .GreaterOrEqual, | |
| 248 | .AssignMul, | |
| 249 | .AssignDiv, | |
| 250 | .AssignMod, | |
| 251 | .AssignAdd, | |
| 252 | .AssignSub, | |
| 253 | .AssignBitShiftLeft, | |
| 254 | .AssignBitShiftRight, | |
| 255 | .AssignBitAnd, | |
| 256 | .AssignBitXor, | |
| 257 | .AssignBitOr, | |
| 258 | .AssignMulWrap, | |
| 259 | .AssignAddWrap, | |
| 260 | .AssignSubWrap, | |
| 261 | .Assign, | |
| 262 | .MergeErrorSets, | |
| 263 | .Mul, | |
| 264 | .Div, | |
| 265 | .Mod, | |
| 266 | .ArrayMult, | |
| 267 | .MulWrap, | |
| 268 | .Add, | |
| 269 | .Sub, | |
| 270 | .ArrayCat, | |
| 271 | .AddWrap, | |
| 272 | .SubWrap, | |
| 273 | .BitShiftLeft, | |
| 274 | .BitShiftRight, | |
| 275 | .BitAnd, | |
| 276 | .BitXor, | |
| 277 | .BitOr, | |
| 278 | .OrElse, | |
| 279 | .BoolAnd, | |
| 280 | .BoolOr, | |
| 281 | .SliceOpen, | |
| 282 | .Slice, | |
| 283 | .Deref, | |
| 284 | .ArrayAccess, | |
| 285 | .ArrayInitOne, | |
| 286 | .ArrayInit, | |
| 287 | .StructInitOne, | |
| 288 | .CallOne, | |
| 289 | .Call, | |
| 290 | .SwitchCaseOne, | |
| 291 | .SwitchRange, | |
| 292 | .FnDecl, | |
| 293 | => return tree.firstToken(datas[node].lhs), | |
| 294 | ||
| 295 | .GlobalVarDecl, | |
| 296 | .LocalVarDecl, | |
| 297 | .SimpleVarDecl, | |
| 298 | .AlignedVarDecl, | |
| 299 | .ArrayType, | |
| 300 | .ArrayTypeSentinel, | |
| 301 | .PtrTypeAligned, | |
| 302 | .PtrTypeSentinel, | |
| 303 | .PtrType, | |
| 304 | .SliceType, | |
| 305 | .StructInit, | |
| 306 | .SwitchCaseMulti, | |
| 307 | .WhileSimple, | |
| 308 | .WhileSimpleOptional, | |
| 309 | .WhileCont, | |
| 310 | .WhileContOptional, | |
| 311 | .While, | |
| 312 | .WhileOptional, | |
| 313 | .WhileError, | |
| 314 | .ForSimple, | |
| 315 | .For, | |
| 316 | .FnProtoSimple, | |
| 317 | .FnProtoSimpleMulti, | |
| 318 | .FnProtoOne, | |
| 319 | .FnProto, | |
| 320 | .ContainerDecl, | |
| 321 | .ContainerDeclArg, | |
| 322 | .TaggedUnion, | |
| 323 | .TaggedUnionEnumTag, | |
| 324 | .ContainerFieldInit, | |
| 325 | .ContainerFieldAlign, | |
| 326 | .ContainerField, | |
| 327 | .AsmOutput, | |
| 328 | .AsmInput, | |
| 329 | .ErrorValue, | |
| 330 | .ErrorUnion, | |
| 331 | => @panic("TODO finish implementing firstToken"), | |
| 194 | 332 | } |
| 195 | return index; | |
| 196 | 333 | } |
| 197 | 334 | |
| 198 | /// Skips over comments. | |
| 199 | pub fn nextToken(self: *const Tree, token_index: TokenIndex) TokenIndex { | |
| 200 | const token_tags = self.tokens.items(.tag); | |
| 201 | var index = token_index + 1; | |
| 202 | while (token_tags[index] == .LineComment) { | |
| 203 | index += 1; | |
| 335 | pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex { | |
| 336 | const tags = tree.nodes.items(.tag); | |
| 337 | const datas = tree.nodes.items(.data); | |
| 338 | const main_tokens = tree.nodes.items(.main_token); | |
| 339 | switch (tags[node]) { | |
| 340 | .Root, | |
| 341 | .UsingNamespace, | |
| 342 | .TestDecl, | |
| 343 | .ErrDefer, | |
| 344 | .Defer, | |
| 345 | .BoolNot, | |
| 346 | .Negation, | |
| 347 | .BitNot, | |
| 348 | .NegationWrap, | |
| 349 | .AddressOf, | |
| 350 | .Try, | |
| 351 | .Await, | |
| 352 | .OptionalType, | |
| 353 | .ArrayInitDotTwo, | |
| 354 | .ArrayInitDot, | |
| 355 | .StructInitDotTwo, | |
| 356 | .StructInitDot, | |
| 357 | .Switch, | |
| 358 | .IfSimple, | |
| 359 | .IfSimpleOptional, | |
| 360 | .If, | |
| 361 | .IfOptional, | |
| 362 | .IfError, | |
| 363 | .Suspend, | |
| 364 | .Resume, | |
| 365 | .Continue, | |
| 366 | .Break, | |
| 367 | .Return, | |
| 368 | .AnyFrameType, | |
| 369 | .OneToken, | |
| 370 | .Identifier, | |
| 371 | .EnumLiteral, | |
| 372 | .MultilineStringLiteral, | |
| 373 | .GroupedExpression, | |
| 374 | .BuiltinCallTwo, | |
| 375 | .BuiltinCall, | |
| 376 | .ErrorSetDecl, | |
| 377 | .AnyType, | |
| 378 | .Comptime, | |
| 379 | .Nosuspend, | |
| 380 | .Block, | |
| 381 | .AsmSimple, | |
| 382 | .Asm, | |
| 383 | .Catch, | |
| 384 | .FieldAccess, | |
| 385 | .UnwrapOptional, | |
| 386 | .EqualEqual, | |
| 387 | .BangEqual, | |
| 388 | .LessThan, | |
| 389 | .GreaterThan, | |
| 390 | .LessOrEqual, | |
| 391 | .GreaterOrEqual, | |
| 392 | .AssignMul, | |
| 393 | .AssignDiv, | |
| 394 | .AssignMod, | |
| 395 | .AssignAdd, | |
| 396 | .AssignSub, | |
| 397 | .AssignBitShiftLeft, | |
| 398 | .AssignBitShiftRight, | |
| 399 | .AssignBitAnd, | |
| 400 | .AssignBitXor, | |
| 401 | .AssignBitOr, | |
| 402 | .AssignMulWrap, | |
| 403 | .AssignAddWrap, | |
| 404 | .AssignSubWrap, | |
| 405 | .Assign, | |
| 406 | .MergeErrorSets, | |
| 407 | .Mul, | |
| 408 | .Div, | |
| 409 | .Mod, | |
| 410 | .ArrayMult, | |
| 411 | .MulWrap, | |
| 412 | .Add, | |
| 413 | .Sub, | |
| 414 | .ArrayCat, | |
| 415 | .AddWrap, | |
| 416 | .SubWrap, | |
| 417 | .BitShiftLeft, | |
| 418 | .BitShiftRight, | |
| 419 | .BitAnd, | |
| 420 | .BitXor, | |
| 421 | .BitOr, | |
| 422 | .OrElse, | |
| 423 | .BoolAnd, | |
| 424 | .BoolOr, | |
| 425 | .SliceOpen, | |
| 426 | .Slice, | |
| 427 | .Deref, | |
| 428 | .ArrayAccess, | |
| 429 | .ArrayInitOne, | |
| 430 | .ArrayInit, | |
| 431 | .StructInitOne, | |
| 432 | .CallOne, | |
| 433 | .Call, | |
| 434 | .SwitchCaseOne, | |
| 435 | .SwitchRange, | |
| 436 | .FnDecl, | |
| 437 | .GlobalVarDecl, | |
| 438 | .LocalVarDecl, | |
| 439 | .SimpleVarDecl, | |
| 440 | .AlignedVarDecl, | |
| 441 | .ArrayType, | |
| 442 | .ArrayTypeSentinel, | |
| 443 | .PtrTypeAligned, | |
| 444 | .PtrTypeSentinel, | |
| 445 | .PtrType, | |
| 446 | .SliceType, | |
| 447 | .StructInit, | |
| 448 | .SwitchCaseMulti, | |
| 449 | .WhileSimple, | |
| 450 | .WhileSimpleOptional, | |
| 451 | .WhileCont, | |
| 452 | .WhileContOptional, | |
| 453 | .While, | |
| 454 | .WhileOptional, | |
| 455 | .WhileError, | |
| 456 | .ForSimple, | |
| 457 | .For, | |
| 458 | .FnProtoSimple, | |
| 459 | .FnProtoSimpleMulti, | |
| 460 | .FnProtoOne, | |
| 461 | .FnProto, | |
| 462 | .ContainerDecl, | |
| 463 | .ContainerDeclArg, | |
| 464 | .TaggedUnion, | |
| 465 | .TaggedUnionEnumTag, | |
| 466 | .ContainerFieldInit, | |
| 467 | .ContainerFieldAlign, | |
| 468 | .ContainerField, | |
| 469 | .AsmOutput, | |
| 470 | .AsmInput, | |
| 471 | .ErrorValue, | |
| 472 | .ErrorUnion, | |
| 473 | => @panic("TODO finish implementing lastToken"), | |
| 204 | 474 | } |
| 205 | return index; | |
| 206 | 475 | } |
| 207 | 476 | }; |
| 208 | 477 | |
| ... | ... | @@ -454,7 +723,7 @@ pub const Node = struct { |
| 454 | 723 | /// lhs is test name token (must be string literal), if any. |
| 455 | 724 | /// rhs is the body node. |
| 456 | 725 | TestDecl, |
| 457 | /// lhs is the index into global_var_decl_list. | |
| 726 | /// lhs is the index into extra_data. | |
| 458 | 727 | /// rhs is the initialization expression, if any. |
| 459 | 728 | GlobalVarDecl, |
| 460 | 729 | /// `var a: x align(y) = rhs` |
| ... | ... | @@ -732,6 +1001,7 @@ pub const Node = struct { |
| 732 | 1001 | /// `nosuspend lhs`. rhs unused. |
| 733 | 1002 | Nosuspend, |
| 734 | 1003 | /// `{}`. `sub_list[lhs..rhs]`. |
| 1004 | /// main_token points at the `{`. | |
| 735 | 1005 | Block, |
| 736 | 1006 | /// `asm(lhs)`. rhs unused. |
| 737 | 1007 | AsmSimple, |
lib/std/zig/parse.zig+1-1| ... | ... | @@ -594,7 +594,7 @@ const Parser = struct { |
| 594 | 594 | p.eatToken(.Keyword_var) orelse |
| 595 | 595 | return null_node; |
| 596 | 596 | |
| 597 | const name_token = try p.expectToken(.Identifier); | |
| 597 | _ = try p.expectToken(.Identifier); | |
| 598 | 598 | const type_node: Node.Index = if (p.eatToken(.Colon) == null) 0 else try p.expectTypeExpr(); |
| 599 | 599 | const align_node = try p.parseByteAlign(); |
| 600 | 600 | const section_node = try p.parseLinkSection(); |
lib/std/zig/parser_test.zig+3702-3723| ... | ... | @@ -3,3727 +3,3704 @@ |
| 3 | 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. |
| 4 | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | 5 | // and substantial portions of the software. |
| 6 | test "zig fmt: convert var to anytype" { | |
| 7 | // TODO remove in next release cycle | |
| 8 | try testTransform( | |
| 9 | \\pub fn main( | |
| 10 | \\ a: var, | |
| 11 | \\ bar: var, | |
| 12 | \\) void {} | |
| 13 | , | |
| 14 | \\pub fn main( | |
| 15 | \\ a: anytype, | |
| 16 | \\ bar: anytype, | |
| 17 | \\) void {} | |
| 18 | \\ | |
| 19 | ); | |
| 20 | } | |
| 21 | ||
| 22 | test "zig fmt: noasync to nosuspend" { | |
| 23 | // TODO: remove this | |
| 24 | try testTransform( | |
| 25 | \\pub fn main() void { | |
| 26 | \\ noasync call(); | |
| 27 | \\} | |
| 28 | , | |
| 29 | \\pub fn main() void { | |
| 30 | \\ nosuspend call(); | |
| 31 | \\} | |
| 32 | \\ | |
| 33 | ); | |
| 34 | } | |
| 35 | ||
| 36 | test "recovery: top level" { | |
| 37 | try testError( | |
| 38 | \\test "" {inline} | |
| 39 | \\test "" {inline} | |
| 40 | , &[_]Error{ | |
| 41 | .ExpectedInlinable, | |
| 42 | .ExpectedInlinable, | |
| 43 | }); | |
| 44 | } | |
| 45 | ||
| 46 | test "recovery: block statements" { | |
| 47 | try testError( | |
| 48 | \\test "" { | |
| 49 | \\ foo + +; | |
| 50 | \\ inline; | |
| 51 | \\} | |
| 52 | , &[_]Error{ | |
| 53 | .InvalidToken, | |
| 54 | .ExpectedInlinable, | |
| 55 | }); | |
| 56 | } | |
| 57 | ||
| 58 | test "recovery: missing comma" { | |
| 59 | try testError( | |
| 60 | \\test "" { | |
| 61 | \\ switch (foo) { | |
| 62 | \\ 2 => {} | |
| 63 | \\ 3 => {} | |
| 64 | \\ else => { | |
| 65 | \\ foo && bar +; | |
| 66 | \\ } | |
| 67 | \\ } | |
| 68 | \\} | |
| 69 | , &[_]Error{ | |
| 70 | .ExpectedToken, | |
| 71 | .ExpectedToken, | |
| 72 | .InvalidAnd, | |
| 73 | .InvalidToken, | |
| 74 | }); | |
| 75 | } | |
| 76 | ||
| 77 | test "recovery: extra qualifier" { | |
| 78 | try testError( | |
| 79 | \\const a: *const const u8; | |
| 80 | \\test "" | |
| 81 | , &[_]Error{ | |
| 82 | .ExtraConstQualifier, | |
| 83 | .ExpectedLBrace, | |
| 84 | }); | |
| 85 | } | |
| 86 | ||
| 87 | test "recovery: missing return type" { | |
| 88 | try testError( | |
| 89 | \\fn foo() { | |
| 90 | \\ a && b; | |
| 91 | \\} | |
| 92 | \\test "" | |
| 93 | , &[_]Error{ | |
| 94 | .ExpectedReturnType, | |
| 95 | .InvalidAnd, | |
| 96 | .ExpectedLBrace, | |
| 97 | }); | |
| 98 | } | |
| 99 | ||
| 100 | test "recovery: continue after invalid decl" { | |
| 101 | try testError( | |
| 102 | \\fn foo { | |
| 103 | \\ inline; | |
| 104 | \\} | |
| 105 | \\pub test "" { | |
| 106 | \\ async a && b; | |
| 107 | \\} | |
| 108 | , &[_]Error{ | |
| 109 | .ExpectedToken, | |
| 110 | .ExpectedPubItem, | |
| 111 | .ExpectedParamList, | |
| 112 | .InvalidAnd, | |
| 113 | }); | |
| 114 | try testError( | |
| 115 | \\threadlocal test "" { | |
| 116 | \\ @a && b; | |
| 117 | \\} | |
| 118 | , &[_]Error{ | |
| 119 | .ExpectedVarDecl, | |
| 120 | .ExpectedParamList, | |
| 121 | .InvalidAnd, | |
| 122 | }); | |
| 123 | } | |
| 124 | ||
| 125 | test "recovery: invalid extern/inline" { | |
| 126 | try testError( | |
| 127 | \\inline test "" { a && b; } | |
| 128 | , &[_]Error{ | |
| 129 | .ExpectedFn, | |
| 130 | .InvalidAnd, | |
| 131 | }); | |
| 132 | try testError( | |
| 133 | \\extern "" test "" { a && b; } | |
| 134 | , &[_]Error{ | |
| 135 | .ExpectedVarDeclOrFn, | |
| 136 | .InvalidAnd, | |
| 137 | }); | |
| 138 | } | |
| 139 | ||
| 140 | test "recovery: missing semicolon" { | |
| 141 | try testError( | |
| 142 | \\test "" { | |
| 143 | \\ comptime a && b | |
| 144 | \\ c && d | |
| 145 | \\ @foo | |
| 146 | \\} | |
| 147 | , &[_]Error{ | |
| 148 | .InvalidAnd, | |
| 149 | .ExpectedToken, | |
| 150 | .InvalidAnd, | |
| 151 | .ExpectedToken, | |
| 152 | .ExpectedParamList, | |
| 153 | .ExpectedToken, | |
| 154 | }); | |
| 155 | } | |
| 156 | ||
| 157 | test "recovery: invalid container members" { | |
| 158 | try testError( | |
| 159 | \\usingnamespace; | |
| 160 | \\foo+ | |
| 161 | \\bar@, | |
| 162 | \\while (a == 2) { test "" {}} | |
| 163 | \\test "" { | |
| 164 | \\ a && b | |
| 165 | \\} | |
| 166 | , &[_]Error{ | |
| 167 | .ExpectedExpr, | |
| 168 | .ExpectedToken, | |
| 169 | .ExpectedToken, | |
| 170 | .ExpectedContainerMembers, | |
| 171 | .InvalidAnd, | |
| 172 | .ExpectedToken, | |
| 173 | }); | |
| 174 | } | |
| 175 | ||
| 176 | test "recovery: invalid parameter" { | |
| 177 | try testError( | |
| 178 | \\fn main() void { | |
| 179 | \\ a(comptime T: type) | |
| 180 | \\} | |
| 181 | , &[_]Error{ | |
| 182 | .ExpectedToken, | |
| 183 | }); | |
| 184 | } | |
| 185 | ||
| 186 | test "recovery: extra '}' at top level" { | |
| 187 | try testError( | |
| 188 | \\}}} | |
| 189 | \\test "" { | |
| 190 | \\ a && b; | |
| 191 | \\} | |
| 192 | , &[_]Error{ | |
| 193 | .ExpectedContainerMembers, | |
| 194 | .ExpectedContainerMembers, | |
| 195 | .ExpectedContainerMembers, | |
| 196 | .InvalidAnd, | |
| 197 | }); | |
| 198 | } | |
| 199 | ||
| 200 | test "recovery: mismatched bracket at top level" { | |
| 201 | try testError( | |
| 202 | \\const S = struct { | |
| 203 | \\ arr: 128]?G | |
| 204 | \\}; | |
| 205 | , &[_]Error{ | |
| 206 | .ExpectedToken, | |
| 207 | }); | |
| 208 | } | |
| 209 | ||
| 210 | test "recovery: invalid global error set access" { | |
| 211 | try testError( | |
| 212 | \\test "" { | |
| 213 | \\ error && foo; | |
| 214 | \\} | |
| 215 | , &[_]Error{ | |
| 216 | .ExpectedToken, | |
| 217 | .ExpectedIdentifier, | |
| 218 | .InvalidAnd, | |
| 219 | }); | |
| 220 | } | |
| 221 | ||
| 222 | test "recovery: invalid asterisk after pointer dereference" { | |
| 223 | try testError( | |
| 224 | \\test "" { | |
| 225 | \\ var sequence = "repeat".*** 10; | |
| 226 | \\} | |
| 227 | , &[_]Error{ | |
| 228 | .AsteriskAfterPointerDereference, | |
| 229 | }); | |
| 230 | try testError( | |
| 231 | \\test "" { | |
| 232 | \\ var sequence = "repeat".** 10&&a; | |
| 233 | \\} | |
| 234 | , &[_]Error{ | |
| 235 | .AsteriskAfterPointerDereference, | |
| 236 | .InvalidAnd, | |
| 237 | }); | |
| 238 | } | |
| 239 | ||
| 240 | test "recovery: missing semicolon after if, for, while stmt" { | |
| 241 | try testError( | |
| 242 | \\test "" { | |
| 243 | \\ if (foo) bar | |
| 244 | \\ for (foo) |a| bar | |
| 245 | \\ while (foo) bar | |
| 246 | \\ a && b; | |
| 247 | \\} | |
| 248 | , &[_]Error{ | |
| 249 | .ExpectedSemiOrElse, | |
| 250 | .ExpectedSemiOrElse, | |
| 251 | .ExpectedSemiOrElse, | |
| 252 | .InvalidAnd, | |
| 253 | }); | |
| 254 | } | |
| 255 | ||
| 256 | test "recovery: invalid comptime" { | |
| 257 | try testError( | |
| 258 | \\comptime | |
| 259 | , &[_]Error{ | |
| 260 | .ExpectedBlockOrField, | |
| 261 | }); | |
| 262 | } | |
| 263 | ||
| 264 | test "recovery: missing block after for/while loops" { | |
| 265 | try testError( | |
| 266 | \\test "" { while (foo) } | |
| 267 | , &[_]Error{ | |
| 268 | .ExpectedBlockOrAssignment, | |
| 269 | }); | |
| 270 | try testError( | |
| 271 | \\test "" { for (foo) |bar| } | |
| 272 | , &[_]Error{ | |
| 273 | .ExpectedBlockOrAssignment, | |
| 274 | }); | |
| 275 | } | |
| 276 | ||
| 277 | test "zig fmt: respect line breaks after var declarations" { | |
| 278 | try testCanonical( | |
| 279 | \\const crc = | |
| 280 | \\ lookup_tables[0][p[7]] ^ | |
| 281 | \\ lookup_tables[1][p[6]] ^ | |
| 282 | \\ lookup_tables[2][p[5]] ^ | |
| 283 | \\ lookup_tables[3][p[4]] ^ | |
| 284 | \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^ | |
| 285 | \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^ | |
| 286 | \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^ | |
| 287 | \\ lookup_tables[7][@truncate(u8, self.crc >> 0)]; | |
| 288 | \\ | |
| 289 | ); | |
| 290 | } | |
| 291 | ||
| 292 | test "zig fmt: multiline string mixed with comments" { | |
| 293 | try testCanonical( | |
| 294 | \\const s1 = | |
| 295 | \\ //\\one | |
| 296 | \\ \\two) | |
| 297 | \\ \\three | |
| 298 | \\; | |
| 299 | \\const s2 = | |
| 300 | \\ \\one | |
| 301 | \\ \\two) | |
| 302 | \\ //\\three | |
| 303 | \\; | |
| 304 | \\const s3 = | |
| 305 | \\ \\one | |
| 306 | \\ //\\two) | |
| 307 | \\ \\three | |
| 308 | \\; | |
| 309 | \\const s4 = | |
| 310 | \\ \\one | |
| 311 | \\ //\\two | |
| 312 | \\ \\three | |
| 313 | \\ //\\four | |
| 314 | \\ \\five | |
| 315 | \\; | |
| 316 | \\const a = | |
| 317 | \\ 1; | |
| 318 | \\ | |
| 319 | ); | |
| 320 | } | |
| 321 | ||
| 322 | test "zig fmt: empty file" { | |
| 323 | try testCanonical( | |
| 324 | \\ | |
| 325 | ); | |
| 326 | } | |
| 327 | ||
| 328 | test "zig fmt: if statment" { | |
| 329 | try testCanonical( | |
| 330 | \\test "" { | |
| 331 | \\ if (optional()) |some| | |
| 332 | \\ bar = some.foo(); | |
| 333 | \\} | |
| 334 | \\ | |
| 335 | ); | |
| 336 | } | |
| 337 | ||
| 338 | test "zig fmt: top-level fields" { | |
| 339 | try testCanonical( | |
| 340 | \\a: did_you_know, | |
| 341 | \\b: all_files_are, | |
| 342 | \\structs: ?x, | |
| 343 | \\ | |
| 344 | ); | |
| 345 | } | |
| 346 | ||
| 347 | test "zig fmt: decl between fields" { | |
| 348 | try testError( | |
| 349 | \\const S = struct { | |
| 350 | \\ const foo = 2; | |
| 351 | \\ const bar = 2; | |
| 352 | \\ const baz = 2; | |
| 353 | \\ a: usize, | |
| 354 | \\ const foo1 = 2; | |
| 355 | \\ const bar1 = 2; | |
| 356 | \\ const baz1 = 2; | |
| 357 | \\ b: usize, | |
| 358 | \\}; | |
| 359 | , &[_]Error{ | |
| 360 | .DeclBetweenFields, | |
| 361 | }); | |
| 362 | } | |
| 363 | ||
| 364 | test "zig fmt: eof after missing comma" { | |
| 365 | try testError( | |
| 366 | \\foo() | |
| 367 | , &[_]Error{ | |
| 368 | .ExpectedToken, | |
| 369 | }); | |
| 370 | } | |
| 371 | ||
| 372 | test "zig fmt: errdefer with payload" { | |
| 373 | try testCanonical( | |
| 374 | \\pub fn main() anyerror!void { | |
| 375 | \\ errdefer |a| x += 1; | |
| 376 | \\ errdefer |a| {} | |
| 377 | \\ errdefer |a| { | |
| 378 | \\ x += 1; | |
| 379 | \\ } | |
| 380 | \\} | |
| 381 | \\ | |
| 382 | ); | |
| 383 | } | |
| 384 | ||
| 385 | test "zig fmt: nosuspend block" { | |
| 386 | try testCanonical( | |
| 387 | \\pub fn main() anyerror!void { | |
| 388 | \\ nosuspend { | |
| 389 | \\ var foo: Foo = .{ .bar = 42 }; | |
| 390 | \\ } | |
| 391 | \\} | |
| 392 | \\ | |
| 393 | ); | |
| 394 | } | |
| 395 | ||
| 396 | test "zig fmt: nosuspend await" { | |
| 397 | try testCanonical( | |
| 398 | \\fn foo() void { | |
| 399 | \\ x = nosuspend await y; | |
| 400 | \\} | |
| 401 | \\ | |
| 402 | ); | |
| 403 | } | |
| 404 | ||
| 405 | test "zig fmt: trailing comma in container declaration" { | |
| 406 | try testCanonical( | |
| 407 | \\const X = struct { foo: i32 }; | |
| 408 | \\const X = struct { foo: i32, bar: i32 }; | |
| 409 | \\const X = struct { foo: i32 = 1, bar: i32 = 2 }; | |
| 410 | \\const X = struct { foo: i32 align(4), bar: i32 align(4) }; | |
| 411 | \\const X = struct { foo: i32 align(4) = 1, bar: i32 align(4) = 2 }; | |
| 412 | \\ | |
| 413 | ); | |
| 414 | try testCanonical( | |
| 415 | \\test "" { | |
| 416 | \\ comptime { | |
| 417 | \\ const X = struct { | |
| 418 | \\ x: i32 | |
| 419 | \\ }; | |
| 420 | \\ } | |
| 421 | \\} | |
| 422 | \\ | |
| 423 | ); | |
| 424 | try testTransform( | |
| 425 | \\const X = struct { | |
| 426 | \\ foo: i32, bar: i8 }; | |
| 427 | , | |
| 428 | \\const X = struct { | |
| 429 | \\ foo: i32, bar: i8 | |
| 430 | \\}; | |
| 431 | \\ | |
| 432 | ); | |
| 433 | } | |
| 434 | ||
| 435 | test "zig fmt: trailing comma in fn parameter list" { | |
| 436 | try testCanonical( | |
| 437 | \\pub fn f( | |
| 438 | \\ a: i32, | |
| 439 | \\ b: i32, | |
| 440 | \\) i32 {} | |
| 441 | \\pub fn f( | |
| 442 | \\ a: i32, | |
| 443 | \\ b: i32, | |
| 444 | \\) align(8) i32 {} | |
| 445 | \\pub fn f( | |
| 446 | \\ a: i32, | |
| 447 | \\ b: i32, | |
| 448 | \\) linksection(".text") i32 {} | |
| 449 | \\pub fn f( | |
| 450 | \\ a: i32, | |
| 451 | \\ b: i32, | |
| 452 | \\) callconv(.C) i32 {} | |
| 453 | \\pub fn f( | |
| 454 | \\ a: i32, | |
| 455 | \\ b: i32, | |
| 456 | \\) align(8) linksection(".text") i32 {} | |
| 457 | \\pub fn f( | |
| 458 | \\ a: i32, | |
| 459 | \\ b: i32, | |
| 460 | \\) align(8) callconv(.C) i32 {} | |
| 461 | \\pub fn f( | |
| 462 | \\ a: i32, | |
| 463 | \\ b: i32, | |
| 464 | \\) align(8) linksection(".text") callconv(.C) i32 {} | |
| 465 | \\pub fn f( | |
| 466 | \\ a: i32, | |
| 467 | \\ b: i32, | |
| 468 | \\) linksection(".text") callconv(.C) i32 {} | |
| 469 | \\ | |
| 470 | ); | |
| 471 | } | |
| 472 | ||
| 473 | test "zig fmt: comptime struct field" { | |
| 474 | try testCanonical( | |
| 475 | \\const Foo = struct { | |
| 476 | \\ a: i32, | |
| 477 | \\ comptime b: i32 = 1234, | |
| 478 | \\}; | |
| 479 | \\ | |
| 480 | ); | |
| 481 | } | |
| 482 | ||
| 483 | test "zig fmt: c pointer type" { | |
| 484 | try testCanonical( | |
| 485 | \\pub extern fn repro() [*c]const u8; | |
| 486 | \\ | |
| 487 | ); | |
| 488 | } | |
| 489 | ||
| 490 | test "zig fmt: builtin call with trailing comma" { | |
| 491 | try testCanonical( | |
| 492 | \\pub fn main() void { | |
| 493 | \\ @breakpoint(); | |
| 494 | \\ _ = @boolToInt(a); | |
| 495 | \\ _ = @call( | |
| 496 | \\ a, | |
| 497 | \\ b, | |
| 498 | \\ c, | |
| 499 | \\ ); | |
| 500 | \\} | |
| 501 | \\ | |
| 502 | ); | |
| 503 | } | |
| 504 | ||
| 505 | test "zig fmt: asm expression with comptime content" { | |
| 506 | try testCanonical( | |
| 507 | \\comptime { | |
| 508 | \\ asm ("foo" ++ "bar"); | |
| 509 | \\} | |
| 510 | \\pub fn main() void { | |
| 511 | \\ asm volatile ("foo" ++ "bar"); | |
| 512 | \\ asm volatile ("foo" ++ "bar" | |
| 513 | \\ : [_] "" (x) | |
| 514 | \\ ); | |
| 515 | \\ asm volatile ("foo" ++ "bar" | |
| 516 | \\ : [_] "" (x) | |
| 517 | \\ : [_] "" (y) | |
| 518 | \\ ); | |
| 519 | \\ asm volatile ("foo" ++ "bar" | |
| 520 | \\ : [_] "" (x) | |
| 521 | \\ : [_] "" (y) | |
| 522 | \\ : "h", "e", "l", "l", "o" | |
| 523 | \\ ); | |
| 524 | \\} | |
| 525 | \\ | |
| 526 | ); | |
| 527 | } | |
| 528 | ||
| 529 | test "zig fmt: anytype struct field" { | |
| 530 | try testCanonical( | |
| 531 | \\pub const Pointer = struct { | |
| 532 | \\ sentinel: anytype, | |
| 533 | \\}; | |
| 534 | \\ | |
| 535 | ); | |
| 536 | } | |
| 537 | ||
| 538 | test "zig fmt: sentinel-terminated array type" { | |
| 539 | try testCanonical( | |
| 540 | \\pub fn cStrToPrefixedFileW(s: [*:0]const u8) ![PATH_MAX_WIDE:0]u16 { | |
| 541 | \\ return sliceToPrefixedFileW(mem.toSliceConst(u8, s)); | |
| 542 | \\} | |
| 543 | \\ | |
| 544 | ); | |
| 545 | } | |
| 546 | ||
| 547 | test "zig fmt: sentinel-terminated slice type" { | |
| 548 | try testCanonical( | |
| 549 | \\pub fn toSlice(self: Buffer) [:0]u8 { | |
| 550 | \\ return self.list.toSlice()[0..self.len()]; | |
| 551 | \\} | |
| 552 | \\ | |
| 553 | ); | |
| 554 | } | |
| 555 | ||
| 556 | test "zig fmt: anon literal in array" { | |
| 557 | try testCanonical( | |
| 558 | \\var arr: [2]Foo = .{ | |
| 559 | \\ .{ .a = 2 }, | |
| 560 | \\ .{ .b = 3 }, | |
| 561 | \\}; | |
| 562 | \\ | |
| 563 | ); | |
| 564 | } | |
| 565 | ||
| 566 | test "zig fmt: alignment in anonymous literal" { | |
| 567 | try testTransform( | |
| 568 | \\const a = .{ | |
| 569 | \\ "U", "L", "F", | |
| 570 | \\ "U'", | |
| 571 | \\ "L'", | |
| 572 | \\ "F'", | |
| 573 | \\}; | |
| 574 | \\ | |
| 575 | , | |
| 576 | \\const a = .{ | |
| 577 | \\ "U", "L", "F", | |
| 578 | \\ "U'", "L'", "F'", | |
| 579 | \\}; | |
| 580 | \\ | |
| 581 | ); | |
| 582 | } | |
| 583 | ||
| 584 | test "zig fmt: anon struct literal syntax" { | |
| 585 | try testCanonical( | |
| 586 | \\const x = .{ | |
| 587 | \\ .a = b, | |
| 588 | \\ .c = d, | |
| 589 | \\}; | |
| 590 | \\ | |
| 591 | ); | |
| 592 | } | |
| 593 | ||
| 594 | test "zig fmt: anon list literal syntax" { | |
| 595 | try testCanonical( | |
| 596 | \\const x = .{ a, b, c }; | |
| 597 | \\ | |
| 598 | ); | |
| 599 | } | |
| 600 | ||
| 601 | test "zig fmt: async function" { | |
| 602 | try testCanonical( | |
| 603 | \\pub const Server = struct { | |
| 604 | \\ handleRequestFn: fn (*Server, *const std.net.Address, File) callconv(.Async) void, | |
| 605 | \\}; | |
| 606 | \\test "hi" { | |
| 607 | \\ var ptr = @ptrCast(fn (i32) callconv(.Async) void, other); | |
| 608 | \\} | |
| 609 | \\ | |
| 610 | ); | |
| 611 | } | |
| 612 | ||
| 613 | test "zig fmt: whitespace fixes" { | |
| 614 | try testTransform("test \"\" {\r\n\tconst hi = x;\r\n}\n// zig fmt: off\ntest \"\"{\r\n\tconst a = b;}\r\n", | |
| 615 | \\test "" { | |
| 616 | \\ const hi = x; | |
| 617 | \\} | |
| 618 | \\// zig fmt: off | |
| 619 | \\test ""{ | |
| 620 | \\ const a = b;} | |
| 621 | \\ | |
| 622 | ); | |
| 623 | } | |
| 624 | ||
| 625 | test "zig fmt: while else err prong with no block" { | |
| 626 | try testCanonical( | |
| 627 | \\test "" { | |
| 628 | \\ const result = while (returnError()) |value| { | |
| 629 | \\ break value; | |
| 630 | \\ } else |err| @as(i32, 2); | |
| 631 | \\ expect(result == 2); | |
| 632 | \\} | |
| 633 | \\ | |
| 634 | ); | |
| 635 | } | |
| 636 | ||
| 637 | test "zig fmt: tagged union with enum values" { | |
| 638 | try testCanonical( | |
| 639 | \\const MultipleChoice2 = union(enum(u32)) { | |
| 640 | \\ Unspecified1: i32, | |
| 641 | \\ A: f32 = 20, | |
| 642 | \\ Unspecified2: void, | |
| 643 | \\ B: bool = 40, | |
| 644 | \\ Unspecified3: i32, | |
| 645 | \\ C: i8 = 60, | |
| 646 | \\ Unspecified4: void, | |
| 647 | \\ D: void = 1000, | |
| 648 | \\ Unspecified5: i32, | |
| 649 | \\}; | |
| 650 | \\ | |
| 651 | ); | |
| 652 | } | |
| 653 | ||
| 654 | test "zig fmt: allowzero pointer" { | |
| 655 | try testCanonical( | |
| 656 | \\const T = [*]allowzero const u8; | |
| 657 | \\ | |
| 658 | ); | |
| 659 | } | |
| 660 | ||
| 661 | test "zig fmt: enum literal" { | |
| 662 | try testCanonical( | |
| 663 | \\const x = .hi; | |
| 664 | \\ | |
| 665 | ); | |
| 666 | } | |
| 667 | ||
| 668 | test "zig fmt: enum literal inside array literal" { | |
| 669 | try testCanonical( | |
| 670 | \\test "enums in arrays" { | |
| 671 | \\ var colors = []Color{.Green}; | |
| 672 | \\ colors = []Colors{ .Green, .Cyan }; | |
| 673 | \\ colors = []Colors{ | |
| 674 | \\ .Grey, | |
| 675 | \\ .Green, | |
| 676 | \\ .Cyan, | |
| 677 | \\ }; | |
| 678 | \\} | |
| 679 | \\ | |
| 680 | ); | |
| 681 | } | |
| 682 | ||
| 683 | test "zig fmt: character literal larger than u8" { | |
| 684 | try testCanonical( | |
| 685 | \\const x = '\u{01f4a9}'; | |
| 686 | \\ | |
| 687 | ); | |
| 688 | } | |
| 689 | ||
| 690 | test "zig fmt: infix operator and then multiline string literal" { | |
| 691 | try testCanonical( | |
| 692 | \\const x = "" ++ | |
| 693 | \\ \\ hi | |
| 694 | \\; | |
| 695 | \\ | |
| 696 | ); | |
| 697 | } | |
| 698 | ||
| 699 | test "zig fmt: infix operator and then multiline string literal" { | |
| 700 | try testCanonical( | |
| 701 | \\const x = "" ++ | |
| 702 | \\ \\ hi0 | |
| 703 | \\ \\ hi1 | |
| 704 | \\ \\ hi2 | |
| 705 | \\; | |
| 706 | \\ | |
| 707 | ); | |
| 708 | } | |
| 709 | ||
| 710 | test "zig fmt: C pointers" { | |
| 711 | try testCanonical( | |
| 712 | \\const Ptr = [*c]i32; | |
| 713 | \\ | |
| 714 | ); | |
| 715 | } | |
| 716 | ||
| 717 | test "zig fmt: threadlocal" { | |
| 718 | try testCanonical( | |
| 719 | \\threadlocal var x: i32 = 1234; | |
| 720 | \\ | |
| 721 | ); | |
| 722 | } | |
| 723 | ||
| 724 | test "zig fmt: linksection" { | |
| 725 | try testCanonical( | |
| 726 | \\export var aoeu: u64 linksection(".text.derp") = 1234; | |
| 727 | \\export fn _start() linksection(".text.boot") callconv(.Naked) noreturn {} | |
| 728 | \\ | |
| 729 | ); | |
| 730 | } | |
| 731 | ||
| 732 | test "zig fmt: correctly move doc comments on struct fields" { | |
| 733 | try testTransform( | |
| 734 | \\pub const section_64 = extern struct { | |
| 735 | \\ sectname: [16]u8, /// name of this section | |
| 736 | \\ segname: [16]u8, /// segment this section goes in | |
| 737 | \\}; | |
| 738 | , | |
| 739 | \\pub const section_64 = extern struct { | |
| 740 | \\ /// name of this section | |
| 741 | \\ sectname: [16]u8, | |
| 742 | \\ /// segment this section goes in | |
| 743 | \\ segname: [16]u8, | |
| 744 | \\}; | |
| 745 | \\ | |
| 746 | ); | |
| 747 | } | |
| 748 | ||
| 749 | test "zig fmt: correctly space struct fields with doc comments" { | |
| 750 | try testTransform( | |
| 751 | \\pub const S = struct { | |
| 752 | \\ /// A | |
| 753 | \\ a: u8, | |
| 754 | \\ /// B | |
| 755 | \\ /// B (cont) | |
| 756 | \\ b: u8, | |
| 757 | \\ | |
| 758 | \\ | |
| 759 | \\ /// C | |
| 760 | \\ c: u8, | |
| 761 | \\}; | |
| 762 | \\ | |
| 763 | , | |
| 764 | \\pub const S = struct { | |
| 765 | \\ /// A | |
| 766 | \\ a: u8, | |
| 767 | \\ /// B | |
| 768 | \\ /// B (cont) | |
| 769 | \\ b: u8, | |
| 770 | \\ | |
| 771 | \\ /// C | |
| 772 | \\ c: u8, | |
| 773 | \\}; | |
| 774 | \\ | |
| 775 | ); | |
| 776 | } | |
| 777 | ||
| 778 | test "zig fmt: doc comments on param decl" { | |
| 779 | try testCanonical( | |
| 780 | \\pub const Allocator = struct { | |
| 781 | \\ shrinkFn: fn ( | |
| 782 | \\ self: *Allocator, | |
| 783 | \\ /// Guaranteed to be the same as what was returned from most recent call to | |
| 784 | \\ /// `allocFn`, `reallocFn`, or `shrinkFn`. | |
| 785 | \\ old_mem: []u8, | |
| 786 | \\ /// Guaranteed to be the same as what was returned from most recent call to | |
| 787 | \\ /// `allocFn`, `reallocFn`, or `shrinkFn`. | |
| 788 | \\ old_alignment: u29, | |
| 789 | \\ /// Guaranteed to be less than or equal to `old_mem.len`. | |
| 790 | \\ new_byte_count: usize, | |
| 791 | \\ /// Guaranteed to be less than or equal to `old_alignment`. | |
| 792 | \\ new_alignment: u29, | |
| 793 | \\ ) []u8, | |
| 794 | \\}; | |
| 795 | \\ | |
| 796 | ); | |
| 797 | } | |
| 798 | ||
| 799 | test "zig fmt: aligned struct field" { | |
| 800 | try testCanonical( | |
| 801 | \\pub const S = struct { | |
| 802 | \\ f: i32 align(32), | |
| 803 | \\}; | |
| 804 | \\ | |
| 805 | ); | |
| 806 | try testCanonical( | |
| 807 | \\pub const S = struct { | |
| 808 | \\ f: i32 align(32) = 1, | |
| 809 | \\}; | |
| 810 | \\ | |
| 811 | ); | |
| 812 | } | |
| 813 | ||
| 814 | test "zig fmt: comment to disable/enable zig fmt first" { | |
| 815 | try testCanonical( | |
| 816 | \\// Test trailing comma syntax | |
| 817 | \\// zig fmt: off | |
| 818 | \\ | |
| 819 | \\const struct_trailing_comma = struct { x: i32, y: i32, }; | |
| 820 | ); | |
| 821 | } | |
| 822 | ||
| 823 | test "zig fmt: comment to disable/enable zig fmt" { | |
| 824 | try testTransform( | |
| 825 | \\const a = b; | |
| 826 | \\// zig fmt: off | |
| 827 | \\const c = d; | |
| 828 | \\// zig fmt: on | |
| 829 | \\const e = f; | |
| 830 | , | |
| 831 | \\const a = b; | |
| 832 | \\// zig fmt: off | |
| 833 | \\const c = d; | |
| 834 | \\// zig fmt: on | |
| 835 | \\const e = f; | |
| 836 | \\ | |
| 837 | ); | |
| 838 | } | |
| 839 | ||
| 840 | test "zig fmt: line comment following 'zig fmt: off'" { | |
| 841 | try testCanonical( | |
| 842 | \\// zig fmt: off | |
| 843 | \\// Test | |
| 844 | \\const e = f; | |
| 845 | ); | |
| 846 | } | |
| 847 | ||
| 848 | test "zig fmt: doc comment following 'zig fmt: off'" { | |
| 849 | try testCanonical( | |
| 850 | \\// zig fmt: off | |
| 851 | \\/// test | |
| 852 | \\const e = f; | |
| 853 | ); | |
| 854 | } | |
| 855 | ||
| 856 | test "zig fmt: line and doc comment following 'zig fmt: off'" { | |
| 857 | try testCanonical( | |
| 858 | \\// zig fmt: off | |
| 859 | \\// test 1 | |
| 860 | \\/// test 2 | |
| 861 | \\const e = f; | |
| 862 | ); | |
| 863 | } | |
| 864 | ||
| 865 | test "zig fmt: doc and line comment following 'zig fmt: off'" { | |
| 866 | try testCanonical( | |
| 867 | \\// zig fmt: off | |
| 868 | \\/// test 1 | |
| 869 | \\// test 2 | |
| 870 | \\const e = f; | |
| 871 | ); | |
| 872 | } | |
| 873 | ||
| 874 | test "zig fmt: alternating 'zig fmt: off' and 'zig fmt: on'" { | |
| 875 | try testCanonical( | |
| 876 | \\// zig fmt: off | |
| 877 | \\// zig fmt: on | |
| 878 | \\// zig fmt: off | |
| 879 | \\const e = f; | |
| 880 | \\// zig fmt: off | |
| 881 | \\// zig fmt: on | |
| 882 | \\// zig fmt: off | |
| 883 | \\const a = b; | |
| 884 | \\// zig fmt: on | |
| 885 | \\const c = d; | |
| 886 | \\// zig fmt: on | |
| 887 | \\ | |
| 888 | ); | |
| 889 | } | |
| 890 | ||
| 891 | test "zig fmt: line comment following 'zig fmt: on'" { | |
| 892 | try testCanonical( | |
| 893 | \\// zig fmt: off | |
| 894 | \\const e = f; | |
| 895 | \\// zig fmt: on | |
| 896 | \\// test | |
| 897 | \\const e = f; | |
| 898 | \\ | |
| 899 | ); | |
| 900 | } | |
| 901 | ||
| 902 | test "zig fmt: doc comment following 'zig fmt: on'" { | |
| 903 | try testCanonical( | |
| 904 | \\// zig fmt: off | |
| 905 | \\const e = f; | |
| 906 | \\// zig fmt: on | |
| 907 | \\/// test | |
| 908 | \\const e = f; | |
| 909 | \\ | |
| 910 | ); | |
| 911 | } | |
| 912 | ||
| 913 | test "zig fmt: line and doc comment following 'zig fmt: on'" { | |
| 914 | try testCanonical( | |
| 915 | \\// zig fmt: off | |
| 916 | \\const e = f; | |
| 917 | \\// zig fmt: on | |
| 918 | \\// test1 | |
| 919 | \\/// test2 | |
| 920 | \\const e = f; | |
| 921 | \\ | |
| 922 | ); | |
| 923 | } | |
| 924 | ||
| 925 | test "zig fmt: doc and line comment following 'zig fmt: on'" { | |
| 926 | try testCanonical( | |
| 927 | \\// zig fmt: off | |
| 928 | \\const e = f; | |
| 929 | \\// zig fmt: on | |
| 930 | \\/// test1 | |
| 931 | \\// test2 | |
| 932 | \\const e = f; | |
| 933 | \\ | |
| 934 | ); | |
| 935 | } | |
| 936 | ||
| 937 | test "zig fmt: pointer of unknown length" { | |
| 938 | try testCanonical( | |
| 939 | \\fn foo(ptr: [*]u8) void {} | |
| 940 | \\ | |
| 941 | ); | |
| 942 | } | |
| 943 | ||
| 944 | test "zig fmt: spaces around slice operator" { | |
| 945 | try testCanonical( | |
| 946 | \\var a = b[c..d]; | |
| 947 | \\var a = b[c..d :0]; | |
| 948 | \\var a = b[c + 1 .. d]; | |
| 949 | \\var a = b[c + 1 ..]; | |
| 950 | \\var a = b[c .. d + 1]; | |
| 951 | \\var a = b[c .. d + 1 :0]; | |
| 952 | \\var a = b[c.a..d.e]; | |
| 953 | \\var a = b[c.a..d.e :0]; | |
| 954 | \\ | |
| 955 | ); | |
| 956 | } | |
| 957 | ||
| 958 | test "zig fmt: async call in if condition" { | |
| 959 | try testCanonical( | |
| 960 | \\comptime { | |
| 961 | \\ if (async b()) { | |
| 962 | \\ a(); | |
| 963 | \\ } | |
| 964 | \\} | |
| 965 | \\ | |
| 966 | ); | |
| 967 | } | |
| 968 | ||
| 969 | test "zig fmt: 2nd arg multiline string" { | |
| 970 | try testCanonical( | |
| 971 | \\comptime { | |
| 972 | \\ cases.addAsm("hello world linux x86_64", | |
| 973 | \\ \\.text | |
| 974 | \\ , "Hello, world!\n"); | |
| 975 | \\} | |
| 976 | \\ | |
| 977 | ); | |
| 978 | } | |
| 979 | ||
| 980 | test "zig fmt: 2nd arg multiline string many args" { | |
| 981 | try testCanonical( | |
| 982 | \\comptime { | |
| 983 | \\ cases.addAsm("hello world linux x86_64", | |
| 984 | \\ \\.text | |
| 985 | \\ , "Hello, world!\n", "Hello, world!\n"); | |
| 986 | \\} | |
| 987 | \\ | |
| 988 | ); | |
| 989 | } | |
| 990 | ||
| 991 | test "zig fmt: final arg multiline string" { | |
| 992 | try testCanonical( | |
| 993 | \\comptime { | |
| 994 | \\ cases.addAsm("hello world linux x86_64", "Hello, world!\n", | |
| 995 | \\ \\.text | |
| 996 | \\ ); | |
| 997 | \\} | |
| 998 | \\ | |
| 999 | ); | |
| 1000 | } | |
| 1001 | ||
| 1002 | test "zig fmt: if condition wraps" { | |
| 1003 | try testTransform( | |
| 1004 | \\comptime { | |
| 1005 | \\ if (cond and | |
| 1006 | \\ cond) { | |
| 1007 | \\ return x; | |
| 1008 | \\ } | |
| 1009 | \\ while (cond and | |
| 1010 | \\ cond) { | |
| 1011 | \\ return x; | |
| 1012 | \\ } | |
| 1013 | \\ if (a == b and | |
| 1014 | \\ c) { | |
| 1015 | \\ a = b; | |
| 1016 | \\ } | |
| 1017 | \\ while (a == b and | |
| 1018 | \\ c) { | |
| 1019 | \\ a = b; | |
| 1020 | \\ } | |
| 1021 | \\ if ((cond and | |
| 1022 | \\ cond)) { | |
| 1023 | \\ return x; | |
| 1024 | \\ } | |
| 1025 | \\ while ((cond and | |
| 1026 | \\ cond)) { | |
| 1027 | \\ return x; | |
| 1028 | \\ } | |
| 1029 | \\ var a = if (a) |*f| x: { | |
| 1030 | \\ break :x &a.b; | |
| 1031 | \\ } else |err| err; | |
| 1032 | \\ var a = if (cond and | |
| 1033 | \\ cond) |*f| | |
| 1034 | \\ x: { | |
| 1035 | \\ break :x &a.b; | |
| 1036 | \\ } else |err| err; | |
| 1037 | \\} | |
| 1038 | , | |
| 1039 | \\comptime { | |
| 1040 | \\ if (cond and | |
| 1041 | \\ cond) | |
| 1042 | \\ { | |
| 1043 | \\ return x; | |
| 1044 | \\ } | |
| 1045 | \\ while (cond and | |
| 1046 | \\ cond) | |
| 1047 | \\ { | |
| 1048 | \\ return x; | |
| 1049 | \\ } | |
| 1050 | \\ if (a == b and | |
| 1051 | \\ c) | |
| 1052 | \\ { | |
| 1053 | \\ a = b; | |
| 1054 | \\ } | |
| 1055 | \\ while (a == b and | |
| 1056 | \\ c) | |
| 1057 | \\ { | |
| 1058 | \\ a = b; | |
| 1059 | \\ } | |
| 1060 | \\ if ((cond and | |
| 1061 | \\ cond)) | |
| 1062 | \\ { | |
| 1063 | \\ return x; | |
| 1064 | \\ } | |
| 1065 | \\ while ((cond and | |
| 1066 | \\ cond)) | |
| 1067 | \\ { | |
| 1068 | \\ return x; | |
| 1069 | \\ } | |
| 1070 | \\ var a = if (a) |*f| x: { | |
| 1071 | \\ break :x &a.b; | |
| 1072 | \\ } else |err| err; | |
| 1073 | \\ var a = if (cond and | |
| 1074 | \\ cond) |*f| | |
| 1075 | \\ x: { | |
| 1076 | \\ break :x &a.b; | |
| 1077 | \\ } else |err| err; | |
| 1078 | \\} | |
| 1079 | \\ | |
| 1080 | ); | |
| 1081 | } | |
| 1082 | ||
| 1083 | test "zig fmt: if condition has line break but must not wrap" { | |
| 1084 | try testCanonical( | |
| 1085 | \\comptime { | |
| 1086 | \\ if (self.user_input_options.put( | |
| 1087 | \\ name, | |
| 1088 | \\ UserInputOption{ | |
| 1089 | \\ .name = name, | |
| 1090 | \\ .used = false, | |
| 1091 | \\ }, | |
| 1092 | \\ ) catch unreachable) |*prev_value| { | |
| 1093 | \\ foo(); | |
| 1094 | \\ bar(); | |
| 1095 | \\ } | |
| 1096 | \\ if (put( | |
| 1097 | \\ a, | |
| 1098 | \\ b, | |
| 1099 | \\ )) { | |
| 1100 | \\ foo(); | |
| 1101 | \\ } | |
| 1102 | \\} | |
| 1103 | \\ | |
| 1104 | ); | |
| 1105 | } | |
| 1106 | ||
| 1107 | test "zig fmt: if condition has line break but must not wrap" { | |
| 1108 | try testCanonical( | |
| 1109 | \\comptime { | |
| 1110 | \\ if (self.user_input_options.put(name, UserInputOption{ | |
| 1111 | \\ .name = name, | |
| 1112 | \\ .used = false, | |
| 1113 | \\ }) catch unreachable) |*prev_value| { | |
| 1114 | \\ foo(); | |
| 1115 | \\ bar(); | |
| 1116 | \\ } | |
| 1117 | \\ if (put( | |
| 1118 | \\ a, | |
| 1119 | \\ b, | |
| 1120 | \\ )) { | |
| 1121 | \\ foo(); | |
| 1122 | \\ } | |
| 1123 | \\} | |
| 1124 | \\ | |
| 1125 | ); | |
| 1126 | } | |
| 1127 | ||
| 1128 | test "zig fmt: function call with multiline argument" { | |
| 1129 | try testCanonical( | |
| 1130 | \\comptime { | |
| 1131 | \\ self.user_input_options.put(name, UserInputOption{ | |
| 1132 | \\ .name = name, | |
| 1133 | \\ .used = false, | |
| 1134 | \\ }); | |
| 1135 | \\} | |
| 1136 | \\ | |
| 1137 | ); | |
| 1138 | } | |
| 1139 | ||
| 1140 | test "zig fmt: same-line doc comment on variable declaration" { | |
| 1141 | try testTransform( | |
| 1142 | \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space | |
| 1143 | \\pub const MAP_FILE = 0x0000; /// map from file (default) | |
| 1144 | \\ | |
| 1145 | \\pub const EMEDIUMTYPE = 124; /// Wrong medium type | |
| 1146 | \\ | |
| 1147 | \\// nameserver query return codes | |
| 1148 | \\pub const ENSROK = 0; /// DNS server returned answer with no data | |
| 1149 | , | |
| 1150 | \\/// allocated from memory, swap space | |
| 1151 | \\pub const MAP_ANONYMOUS = 0x1000; | |
| 1152 | \\/// map from file (default) | |
| 1153 | \\pub const MAP_FILE = 0x0000; | |
| 1154 | \\ | |
| 1155 | \\/// Wrong medium type | |
| 1156 | \\pub const EMEDIUMTYPE = 124; | |
| 1157 | \\ | |
| 1158 | \\// nameserver query return codes | |
| 1159 | \\/// DNS server returned answer with no data | |
| 1160 | \\pub const ENSROK = 0; | |
| 1161 | \\ | |
| 1162 | ); | |
| 1163 | } | |
| 1164 | ||
| 1165 | test "zig fmt: if-else with comment before else" { | |
| 1166 | try testCanonical( | |
| 1167 | \\comptime { | |
| 1168 | \\ // cexp(finite|nan +- i inf|nan) = nan + i nan | |
| 1169 | \\ if ((hx & 0x7fffffff) != 0x7f800000) { | |
| 1170 | \\ return Complex(f32).new(y - y, y - y); | |
| 1171 | \\ } // cexp(-inf +- i inf|nan) = 0 + i0 | |
| 1172 | \\ else if (hx & 0x80000000 != 0) { | |
| 1173 | \\ return Complex(f32).new(0, 0); | |
| 1174 | \\ } // cexp(+inf +- i inf|nan) = inf + i nan | |
| 1175 | \\ else { | |
| 1176 | \\ return Complex(f32).new(x, y - y); | |
| 1177 | \\ } | |
| 1178 | \\} | |
| 1179 | \\ | |
| 1180 | ); | |
| 1181 | } | |
| 1182 | ||
| 1183 | test "zig fmt: if nested" { | |
| 1184 | try testCanonical( | |
| 1185 | \\pub fn foo() void { | |
| 1186 | \\ return if ((aInt & bInt) >= 0) | |
| 1187 | \\ if (aInt < bInt) | |
| 1188 | \\ GE_LESS | |
| 1189 | \\ else if (aInt == bInt) | |
| 1190 | \\ GE_EQUAL | |
| 1191 | \\ else | |
| 1192 | \\ GE_GREATER | |
| 1193 | \\ else if (aInt > bInt) | |
| 1194 | \\ GE_LESS | |
| 1195 | \\ else if (aInt == bInt) | |
| 1196 | \\ GE_EQUAL | |
| 1197 | \\ else | |
| 1198 | \\ GE_GREATER; | |
| 1199 | \\} | |
| 1200 | \\ | |
| 1201 | ); | |
| 1202 | } | |
| 1203 | ||
| 1204 | test "zig fmt: respect line breaks in if-else" { | |
| 1205 | try testCanonical( | |
| 1206 | \\comptime { | |
| 1207 | \\ return if (cond) a else b; | |
| 1208 | \\ return if (cond) | |
| 1209 | \\ a | |
| 1210 | \\ else | |
| 1211 | \\ b; | |
| 1212 | \\ return if (cond) | |
| 1213 | \\ a | |
| 1214 | \\ else if (cond) | |
| 1215 | \\ b | |
| 1216 | \\ else | |
| 1217 | \\ c; | |
| 1218 | \\} | |
| 1219 | \\ | |
| 1220 | ); | |
| 1221 | } | |
| 1222 | ||
| 1223 | test "zig fmt: respect line breaks after infix operators" { | |
| 1224 | try testCanonical( | |
| 1225 | \\comptime { | |
| 1226 | \\ self.crc = | |
| 1227 | \\ lookup_tables[0][p[7]] ^ | |
| 1228 | \\ lookup_tables[1][p[6]] ^ | |
| 1229 | \\ lookup_tables[2][p[5]] ^ | |
| 1230 | \\ lookup_tables[3][p[4]] ^ | |
| 1231 | \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^ | |
| 1232 | \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^ | |
| 1233 | \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^ | |
| 1234 | \\ lookup_tables[7][@truncate(u8, self.crc >> 0)]; | |
| 1235 | \\} | |
| 1236 | \\ | |
| 1237 | ); | |
| 1238 | } | |
| 1239 | ||
| 1240 | test "zig fmt: fn decl with trailing comma" { | |
| 1241 | try testTransform( | |
| 1242 | \\fn foo(a: i32, b: i32,) void {} | |
| 1243 | , | |
| 1244 | \\fn foo( | |
| 1245 | \\ a: i32, | |
| 1246 | \\ b: i32, | |
| 1247 | \\) void {} | |
| 1248 | \\ | |
| 1249 | ); | |
| 1250 | } | |
| 1251 | ||
| 1252 | test "zig fmt: enum decl with no trailing comma" { | |
| 1253 | try testTransform( | |
| 1254 | \\const StrLitKind = enum {Normal, C}; | |
| 1255 | , | |
| 1256 | \\const StrLitKind = enum { Normal, C }; | |
| 1257 | \\ | |
| 1258 | ); | |
| 1259 | } | |
| 1260 | ||
| 1261 | test "zig fmt: switch comment before prong" { | |
| 1262 | try testCanonical( | |
| 1263 | \\comptime { | |
| 1264 | \\ switch (a) { | |
| 1265 | \\ // hi | |
| 1266 | \\ 0 => {}, | |
| 1267 | \\ } | |
| 1268 | \\} | |
| 1269 | \\ | |
| 1270 | ); | |
| 1271 | } | |
| 1272 | ||
| 1273 | test "zig fmt: struct literal no trailing comma" { | |
| 1274 | try testTransform( | |
| 1275 | \\const a = foo{ .x = 1, .y = 2 }; | |
| 1276 | \\const a = foo{ .x = 1, | |
| 1277 | \\ .y = 2 }; | |
| 1278 | , | |
| 1279 | \\const a = foo{ .x = 1, .y = 2 }; | |
| 1280 | \\const a = foo{ | |
| 1281 | \\ .x = 1, | |
| 1282 | \\ .y = 2, | |
| 1283 | \\}; | |
| 1284 | \\ | |
| 1285 | ); | |
| 1286 | } | |
| 1287 | ||
| 1288 | test "zig fmt: struct literal containing a multiline expression" { | |
| 1289 | try testTransform( | |
| 1290 | \\const a = A{ .x = if (f1()) 10 else 20 }; | |
| 1291 | \\const a = A{ .x = if (f1()) 10 else 20, }; | |
| 1292 | \\const a = A{ .x = if (f1()) | |
| 1293 | \\ 10 else 20 }; | |
| 1294 | \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 }; | |
| 1295 | \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100, }; | |
| 1296 | \\const a = A{ .x = if (f1()) | |
| 1297 | \\ 10 else 20}; | |
| 1298 | \\const a = A{ .x = switch(g) {0 => "ok", else => "no"} }; | |
| 1299 | \\ | |
| 1300 | , | |
| 1301 | \\const a = A{ .x = if (f1()) 10 else 20 }; | |
| 1302 | \\const a = A{ | |
| 1303 | \\ .x = if (f1()) 10 else 20, | |
| 1304 | \\}; | |
| 1305 | \\const a = A{ | |
| 1306 | \\ .x = if (f1()) | |
| 1307 | \\ 10 | |
| 1308 | \\ else | |
| 1309 | \\ 20, | |
| 1310 | \\}; | |
| 1311 | \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 }; | |
| 1312 | \\const a = A{ | |
| 1313 | \\ .x = if (f1()) 10 else 20, | |
| 1314 | \\ .y = f2() + 100, | |
| 1315 | \\}; | |
| 1316 | \\const a = A{ | |
| 1317 | \\ .x = if (f1()) | |
| 1318 | \\ 10 | |
| 1319 | \\ else | |
| 1320 | \\ 20, | |
| 1321 | \\}; | |
| 1322 | \\const a = A{ | |
| 1323 | \\ .x = switch (g) { | |
| 1324 | \\ 0 => "ok", | |
| 1325 | \\ else => "no", | |
| 1326 | \\ }, | |
| 1327 | \\}; | |
| 1328 | \\ | |
| 1329 | ); | |
| 1330 | } | |
| 1331 | ||
| 1332 | test "zig fmt: array literal with hint" { | |
| 1333 | try testTransform( | |
| 1334 | \\const a = []u8{ | |
| 1335 | \\ 1, 2, // | |
| 1336 | \\ 3, | |
| 1337 | \\ 4, | |
| 1338 | \\ 5, | |
| 1339 | \\ 6, | |
| 1340 | \\ 7 }; | |
| 1341 | \\const a = []u8{ | |
| 1342 | \\ 1, 2, // | |
| 1343 | \\ 3, | |
| 1344 | \\ 4, | |
| 1345 | \\ 5, | |
| 1346 | \\ 6, | |
| 1347 | \\ 7, 8 }; | |
| 1348 | \\const a = []u8{ | |
| 1349 | \\ 1, 2, // | |
| 1350 | \\ 3, | |
| 1351 | \\ 4, | |
| 1352 | \\ 5, | |
| 1353 | \\ 6, // blah | |
| 1354 | \\ 7, 8 }; | |
| 1355 | \\const a = []u8{ | |
| 1356 | \\ 1, 2, // | |
| 1357 | \\ 3, // | |
| 1358 | \\ 4, | |
| 1359 | \\ 5, | |
| 1360 | \\ 6, | |
| 1361 | \\ 7 }; | |
| 1362 | \\const a = []u8{ | |
| 1363 | \\ 1, | |
| 1364 | \\ 2, | |
| 1365 | \\ 3, 4, // | |
| 1366 | \\ 5, 6, // | |
| 1367 | \\ 7, 8, // | |
| 1368 | \\}; | |
| 1369 | , | |
| 1370 | \\const a = []u8{ | |
| 1371 | \\ 1, 2, | |
| 1372 | \\ 3, 4, | |
| 1373 | \\ 5, 6, | |
| 1374 | \\ 7, | |
| 1375 | \\}; | |
| 1376 | \\const a = []u8{ | |
| 1377 | \\ 1, 2, | |
| 1378 | \\ 3, 4, | |
| 1379 | \\ 5, 6, | |
| 1380 | \\ 7, 8, | |
| 1381 | \\}; | |
| 1382 | \\const a = []u8{ | |
| 1383 | \\ 1, 2, | |
| 1384 | \\ 3, 4, | |
| 1385 | \\ 5, | |
| 1386 | \\ 6, // blah | |
| 1387 | \\ 7, | |
| 1388 | \\ 8, | |
| 1389 | \\}; | |
| 1390 | \\const a = []u8{ | |
| 1391 | \\ 1, 2, | |
| 1392 | \\ 3, // | |
| 1393 | \\ 4, | |
| 1394 | \\ 5, 6, | |
| 1395 | \\ 7, | |
| 1396 | \\}; | |
| 1397 | \\const a = []u8{ | |
| 1398 | \\ 1, | |
| 1399 | \\ 2, | |
| 1400 | \\ 3, | |
| 1401 | \\ 4, | |
| 1402 | \\ 5, | |
| 1403 | \\ 6, | |
| 1404 | \\ 7, | |
| 1405 | \\ 8, | |
| 1406 | \\}; | |
| 1407 | \\ | |
| 1408 | ); | |
| 1409 | } | |
| 1410 | ||
| 1411 | test "zig fmt: array literal veritical column alignment" { | |
| 1412 | try testTransform( | |
| 1413 | \\const a = []u8{ | |
| 1414 | \\ 1000, 200, | |
| 1415 | \\ 30, 4, | |
| 1416 | \\ 50000, 60 | |
| 1417 | \\}; | |
| 1418 | \\const a = []u8{0, 1, 2, 3, 40, | |
| 1419 | \\ 4,5,600,7, | |
| 1420 | \\ 80, | |
| 1421 | \\ 9, 10, 11, 0, 13, 14, 15}; | |
| 1422 | \\ | |
| 1423 | , | |
| 1424 | \\const a = []u8{ | |
| 1425 | \\ 1000, 200, | |
| 1426 | \\ 30, 4, | |
| 1427 | \\ 50000, 60, | |
| 1428 | \\}; | |
| 1429 | \\const a = []u8{ | |
| 1430 | \\ 0, 1, 2, 3, 40, | |
| 1431 | \\ 4, 5, 600, 7, 80, | |
| 1432 | \\ 9, 10, 11, 0, 13, | |
| 1433 | \\ 14, 15, | |
| 1434 | \\}; | |
| 1435 | \\ | |
| 1436 | ); | |
| 1437 | } | |
| 1438 | ||
| 1439 | test "zig fmt: multiline string with backslash at end of line" { | |
| 1440 | try testCanonical( | |
| 1441 | \\comptime { | |
| 1442 | \\ err( | |
| 1443 | \\ \\\ | |
| 1444 | \\ ); | |
| 1445 | \\} | |
| 1446 | \\ | |
| 1447 | ); | |
| 1448 | } | |
| 1449 | ||
| 1450 | test "zig fmt: multiline string parameter in fn call with trailing comma" { | |
| 1451 | try testCanonical( | |
| 1452 | \\fn foo() void { | |
| 1453 | \\ try stdout.print( | |
| 1454 | \\ \\ZIG_CMAKE_BINARY_DIR {} | |
| 1455 | \\ \\ZIG_C_HEADER_FILES {} | |
| 1456 | \\ \\ZIG_DIA_GUIDS_LIB {} | |
| 1457 | \\ \\ | |
| 1458 | \\ , | |
| 1459 | \\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR), | |
| 1460 | \\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER), | |
| 1461 | \\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB), | |
| 1462 | \\ ); | |
| 1463 | \\} | |
| 1464 | \\ | |
| 1465 | ); | |
| 1466 | } | |
| 1467 | ||
| 1468 | test "zig fmt: trailing comma on fn call" { | |
| 1469 | try testCanonical( | |
| 1470 | \\comptime { | |
| 1471 | \\ var module = try Module.create( | |
| 1472 | \\ allocator, | |
| 1473 | \\ zig_lib_dir, | |
| 1474 | \\ full_cache_dir, | |
| 1475 | \\ ); | |
| 1476 | \\} | |
| 1477 | \\ | |
| 1478 | ); | |
| 1479 | } | |
| 1480 | ||
| 1481 | test "zig fmt: multi line arguments without last comma" { | |
| 1482 | try testTransform( | |
| 1483 | \\pub fn foo( | |
| 1484 | \\ a: usize, | |
| 1485 | \\ b: usize, | |
| 1486 | \\ c: usize, | |
| 1487 | \\ d: usize | |
| 1488 | \\) usize { | |
| 1489 | \\ return a + b + c + d; | |
| 1490 | \\} | |
| 1491 | \\ | |
| 1492 | , | |
| 1493 | \\pub fn foo(a: usize, b: usize, c: usize, d: usize) usize { | |
| 1494 | \\ return a + b + c + d; | |
| 1495 | \\} | |
| 1496 | \\ | |
| 1497 | ); | |
| 1498 | } | |
| 1499 | ||
| 1500 | test "zig fmt: empty block with only comment" { | |
| 1501 | try testCanonical( | |
| 1502 | \\comptime { | |
| 1503 | \\ { | |
| 1504 | \\ // comment | |
| 1505 | \\ } | |
| 1506 | \\} | |
| 1507 | \\ | |
| 1508 | ); | |
| 1509 | } | |
| 1510 | ||
| 1511 | test "zig fmt: no trailing comma on struct decl" { | |
| 1512 | try testCanonical( | |
| 1513 | \\const RoundParam = struct { | |
| 1514 | \\ k: usize, s: u32, t: u32 | |
| 1515 | \\}; | |
| 1516 | \\ | |
| 1517 | ); | |
| 1518 | } | |
| 1519 | ||
| 1520 | test "zig fmt: extra newlines at the end" { | |
| 1521 | try testTransform( | |
| 1522 | \\const a = b; | |
| 1523 | \\ | |
| 1524 | \\ | |
| 1525 | \\ | |
| 1526 | , | |
| 1527 | \\const a = b; | |
| 1528 | \\ | |
| 1529 | ); | |
| 1530 | } | |
| 1531 | ||
| 1532 | test "zig fmt: simple asm" { | |
| 1533 | try testTransform( | |
| 1534 | \\comptime { | |
| 1535 | \\ asm volatile ( | |
| 1536 | \\ \\.globl aoeu; | |
| 1537 | \\ \\.type aoeu, @function; | |
| 1538 | \\ \\.set aoeu, derp; | |
| 1539 | \\ ); | |
| 1540 | \\ | |
| 1541 | \\ asm ("not real assembly" | |
| 1542 | \\ :[a] "x" (x),); | |
| 1543 | \\ asm ("not real assembly" | |
| 1544 | \\ :[a] "x" (->i32),:[a] "x" (1),); | |
| 1545 | \\ asm ("still not real assembly" | |
| 1546 | \\ :::"a","b",); | |
| 1547 | \\} | |
| 1548 | , | |
| 1549 | \\comptime { | |
| 1550 | \\ asm volatile ( | |
| 1551 | \\ \\.globl aoeu; | |
| 1552 | \\ \\.type aoeu, @function; | |
| 1553 | \\ \\.set aoeu, derp; | |
| 1554 | \\ ); | |
| 1555 | \\ | |
| 1556 | \\ asm ("not real assembly" | |
| 1557 | \\ : [a] "x" (x) | |
| 1558 | \\ ); | |
| 1559 | \\ asm ("not real assembly" | |
| 1560 | \\ : [a] "x" (-> i32) | |
| 1561 | \\ : [a] "x" (1) | |
| 1562 | \\ ); | |
| 1563 | \\ asm ("still not real assembly" | |
| 1564 | \\ : | |
| 1565 | \\ : | |
| 1566 | \\ : "a", "b" | |
| 1567 | \\ ); | |
| 1568 | \\} | |
| 1569 | \\ | |
| 1570 | ); | |
| 1571 | } | |
| 1572 | ||
| 1573 | test "zig fmt: nested struct literal with one item" { | |
| 1574 | try testCanonical( | |
| 1575 | \\const a = foo{ | |
| 1576 | \\ .item = bar{ .a = b }, | |
| 1577 | \\}; | |
| 1578 | \\ | |
| 1579 | ); | |
| 1580 | } | |
| 1581 | ||
| 1582 | test "zig fmt: switch cases trailing comma" { | |
| 1583 | try testTransform( | |
| 1584 | \\fn switch_cases(x: i32) void { | |
| 1585 | \\ switch (x) { | |
| 1586 | \\ 1,2,3 => {}, | |
| 1587 | \\ 4,5, => {}, | |
| 1588 | \\ 6... 8, => {}, | |
| 1589 | \\ else => {}, | |
| 1590 | \\ } | |
| 1591 | \\} | |
| 1592 | , | |
| 1593 | \\fn switch_cases(x: i32) void { | |
| 1594 | \\ switch (x) { | |
| 1595 | \\ 1, 2, 3 => {}, | |
| 1596 | \\ 4, | |
| 1597 | \\ 5, | |
| 1598 | \\ => {}, | |
| 1599 | \\ 6...8 => {}, | |
| 1600 | \\ else => {}, | |
| 1601 | \\ } | |
| 1602 | \\} | |
| 1603 | \\ | |
| 1604 | ); | |
| 1605 | } | |
| 1606 | ||
| 1607 | test "zig fmt: slice align" { | |
| 1608 | try testCanonical( | |
| 1609 | \\const A = struct { | |
| 1610 | \\ items: []align(A) T, | |
| 1611 | \\}; | |
| 1612 | \\ | |
| 1613 | ); | |
| 1614 | } | |
| 1615 | ||
| 1616 | test "zig fmt: add trailing comma to array literal" { | |
| 1617 | try testTransform( | |
| 1618 | \\comptime { | |
| 1619 | \\ return []u16{'m', 's', 'y', 's', '-' // hi | |
| 1620 | \\ }; | |
| 1621 | \\ return []u16{'m', 's', 'y', 's', | |
| 1622 | \\ '-'}; | |
| 1623 | \\ return []u16{'m', 's', 'y', 's', '-'}; | |
| 1624 | \\} | |
| 1625 | , | |
| 1626 | \\comptime { | |
| 1627 | \\ return []u16{ | |
| 1628 | \\ 'm', 's', 'y', 's', '-', // hi | |
| 1629 | \\ }; | |
| 1630 | \\ return []u16{ | |
| 1631 | \\ 'm', 's', 'y', 's', | |
| 1632 | \\ '-', | |
| 1633 | \\ }; | |
| 1634 | \\ return []u16{ 'm', 's', 'y', 's', '-' }; | |
| 1635 | \\} | |
| 1636 | \\ | |
| 1637 | ); | |
| 1638 | } | |
| 1639 | ||
| 1640 | test "zig fmt: first thing in file is line comment" { | |
| 1641 | try testCanonical( | |
| 1642 | \\// Introspection and determination of system libraries needed by zig. | |
| 1643 | \\ | |
| 1644 | \\// Introspection and determination of system libraries needed by zig. | |
| 1645 | \\ | |
| 1646 | \\const std = @import("std"); | |
| 1647 | \\ | |
| 1648 | ); | |
| 1649 | } | |
| 1650 | ||
| 1651 | test "zig fmt: line comment after doc comment" { | |
| 1652 | try testCanonical( | |
| 1653 | \\/// doc comment | |
| 1654 | \\// line comment | |
| 1655 | \\fn foo() void {} | |
| 1656 | \\ | |
| 1657 | ); | |
| 1658 | } | |
| 1659 | ||
| 1660 | test "zig fmt: float literal with exponent" { | |
| 1661 | try testCanonical( | |
| 1662 | \\test "bit field alignment" { | |
| 1663 | \\ assert(@TypeOf(&blah.b) == *align(1:3:6) const u3); | |
| 1664 | \\} | |
| 1665 | \\ | |
| 1666 | ); | |
| 1667 | } | |
| 1668 | ||
| 1669 | test "zig fmt: float literal with exponent" { | |
| 1670 | try testCanonical( | |
| 1671 | \\test "aoeu" { | |
| 1672 | \\ switch (state) { | |
| 1673 | \\ TermState.Start => switch (c) { | |
| 1674 | \\ '\x1b' => state = TermState.Escape, | |
| 1675 | \\ else => try out.writeByte(c), | |
| 1676 | \\ }, | |
| 1677 | \\ } | |
| 1678 | \\} | |
| 1679 | \\ | |
| 1680 | ); | |
| 1681 | } | |
| 1682 | test "zig fmt: float literal with exponent" { | |
| 1683 | try testCanonical( | |
| 1684 | \\pub const f64_true_min = 4.94065645841246544177e-324; | |
| 1685 | \\const threshold = 0x1.a827999fcef32p+1022; | |
| 1686 | \\ | |
| 1687 | ); | |
| 1688 | } | |
| 1689 | ||
| 1690 | test "zig fmt: if-else end of comptime" { | |
| 1691 | try testCanonical( | |
| 1692 | \\comptime { | |
| 1693 | \\ if (a) { | |
| 1694 | \\ b(); | |
| 1695 | \\ } else { | |
| 1696 | \\ b(); | |
| 1697 | \\ } | |
| 1698 | \\} | |
| 1699 | \\ | |
| 1700 | ); | |
| 1701 | } | |
| 1702 | ||
| 1703 | test "zig fmt: nested blocks" { | |
| 1704 | try testCanonical( | |
| 1705 | \\comptime { | |
| 1706 | \\ { | |
| 1707 | \\ { | |
| 1708 | \\ { | |
| 1709 | \\ a(); | |
| 1710 | \\ } | |
| 1711 | \\ } | |
| 1712 | \\ } | |
| 1713 | \\} | |
| 1714 | \\ | |
| 1715 | ); | |
| 1716 | } | |
| 1717 | ||
| 1718 | test "zig fmt: block with same line comment after end brace" { | |
| 1719 | try testCanonical( | |
| 1720 | \\comptime { | |
| 1721 | \\ { | |
| 1722 | \\ b(); | |
| 1723 | \\ } // comment | |
| 1724 | \\} | |
| 1725 | \\ | |
| 1726 | ); | |
| 1727 | } | |
| 1728 | ||
| 1729 | test "zig fmt: statements with comment between" { | |
| 1730 | try testCanonical( | |
| 1731 | \\comptime { | |
| 1732 | \\ a = b; | |
| 1733 | \\ // comment | |
| 1734 | \\ a = b; | |
| 1735 | \\} | |
| 1736 | \\ | |
| 1737 | ); | |
| 1738 | } | |
| 1739 | ||
| 1740 | test "zig fmt: statements with empty line between" { | |
| 1741 | try testCanonical( | |
| 1742 | \\comptime { | |
| 1743 | \\ a = b; | |
| 1744 | \\ | |
| 1745 | \\ a = b; | |
| 1746 | \\} | |
| 1747 | \\ | |
| 1748 | ); | |
| 1749 | } | |
| 1750 | ||
| 1751 | test "zig fmt: ptr deref operator and unwrap optional operator" { | |
| 1752 | try testCanonical( | |
| 1753 | \\const a = b.*; | |
| 1754 | \\const a = b.?; | |
| 1755 | \\ | |
| 1756 | ); | |
| 1757 | } | |
| 1758 | ||
| 1759 | test "zig fmt: comment after if before another if" { | |
| 1760 | try testCanonical( | |
| 1761 | \\test "aoeu" { | |
| 1762 | \\ // comment | |
| 1763 | \\ if (x) { | |
| 1764 | \\ bar(); | |
| 1765 | \\ } | |
| 1766 | \\} | |
| 1767 | \\ | |
| 1768 | \\test "aoeu" { | |
| 1769 | \\ if (x) { | |
| 1770 | \\ foo(); | |
| 1771 | \\ } | |
| 1772 | \\ // comment | |
| 1773 | \\ if (x) { | |
| 1774 | \\ bar(); | |
| 1775 | \\ } | |
| 1776 | \\} | |
| 1777 | \\ | |
| 1778 | ); | |
| 1779 | } | |
| 1780 | ||
| 1781 | test "zig fmt: line comment between if block and else keyword" { | |
| 1782 | try testCanonical( | |
| 1783 | \\test "aoeu" { | |
| 1784 | \\ // cexp(finite|nan +- i inf|nan) = nan + i nan | |
| 1785 | \\ if ((hx & 0x7fffffff) != 0x7f800000) { | |
| 1786 | \\ return Complex(f32).new(y - y, y - y); | |
| 1787 | \\ } | |
| 1788 | \\ // cexp(-inf +- i inf|nan) = 0 + i0 | |
| 1789 | \\ else if (hx & 0x80000000 != 0) { | |
| 1790 | \\ return Complex(f32).new(0, 0); | |
| 1791 | \\ } | |
| 1792 | \\ // cexp(+inf +- i inf|nan) = inf + i nan | |
| 1793 | \\ // another comment | |
| 1794 | \\ else { | |
| 1795 | \\ return Complex(f32).new(x, y - y); | |
| 1796 | \\ } | |
| 1797 | \\} | |
| 1798 | \\ | |
| 1799 | ); | |
| 1800 | } | |
| 1801 | ||
| 1802 | test "zig fmt: same line comments in expression" { | |
| 1803 | try testCanonical( | |
| 1804 | \\test "aoeu" { | |
| 1805 | \\ const x = ( // a | |
| 1806 | \\ 0 // b | |
| 1807 | \\ ); // c | |
| 1808 | \\} | |
| 1809 | \\ | |
| 1810 | ); | |
| 1811 | } | |
| 1812 | ||
| 1813 | test "zig fmt: add comma on last switch prong" { | |
| 1814 | try testTransform( | |
| 1815 | \\test "aoeu" { | |
| 1816 | \\switch (self.init_arg_expr) { | |
| 1817 | \\ InitArg.Type => |t| { }, | |
| 1818 | \\ InitArg.None, | |
| 1819 | \\ InitArg.Enum => { } | |
| 1820 | \\} | |
| 1821 | \\ switch (self.init_arg_expr) { | |
| 1822 | \\ InitArg.Type => |t| { }, | |
| 1823 | \\ InitArg.None, | |
| 1824 | \\ InitArg.Enum => { }//line comment | |
| 1825 | \\ } | |
| 1826 | \\} | |
| 1827 | , | |
| 1828 | \\test "aoeu" { | |
| 1829 | \\ switch (self.init_arg_expr) { | |
| 1830 | \\ InitArg.Type => |t| {}, | |
| 1831 | \\ InitArg.None, InitArg.Enum => {}, | |
| 1832 | \\ } | |
| 1833 | \\ switch (self.init_arg_expr) { | |
| 1834 | \\ InitArg.Type => |t| {}, | |
| 1835 | \\ InitArg.None, InitArg.Enum => {}, //line comment | |
| 1836 | \\ } | |
| 1837 | \\} | |
| 1838 | \\ | |
| 1839 | ); | |
| 1840 | } | |
| 1841 | ||
| 1842 | test "zig fmt: same-line comment after a statement" { | |
| 1843 | try testCanonical( | |
| 1844 | \\test "" { | |
| 1845 | \\ a = b; | |
| 1846 | \\ debug.assert(H.digest_size <= H.block_size); // HMAC makes this assumption | |
| 1847 | \\ a = b; | |
| 1848 | \\} | |
| 1849 | \\ | |
| 1850 | ); | |
| 1851 | } | |
| 1852 | ||
| 1853 | test "zig fmt: same-line comment after var decl in struct" { | |
| 1854 | try testCanonical( | |
| 1855 | \\pub const vfs_cap_data = extern struct { | |
| 1856 | \\ const Data = struct {}; // when on disk. | |
| 1857 | \\}; | |
| 1858 | \\ | |
| 1859 | ); | |
| 1860 | } | |
| 1861 | ||
| 1862 | test "zig fmt: same-line comment after field decl" { | |
| 1863 | try testCanonical( | |
| 1864 | \\pub const dirent = extern struct { | |
| 1865 | \\ d_name: u8, | |
| 1866 | \\ d_name: u8, // comment 1 | |
| 1867 | \\ d_name: u8, | |
| 1868 | \\ d_name: u8, // comment 2 | |
| 1869 | \\ d_name: u8, | |
| 1870 | \\}; | |
| 1871 | \\ | |
| 1872 | ); | |
| 1873 | } | |
| 1874 | ||
| 1875 | test "zig fmt: same-line comment after switch prong" { | |
| 1876 | try testCanonical( | |
| 1877 | \\test "" { | |
| 1878 | \\ switch (err) { | |
| 1879 | \\ error.PathAlreadyExists => {}, // comment 2 | |
| 1880 | \\ else => return err, // comment 1 | |
| 1881 | \\ } | |
| 1882 | \\} | |
| 1883 | \\ | |
| 1884 | ); | |
| 1885 | } | |
| 1886 | ||
| 1887 | test "zig fmt: same-line comment after non-block if expression" { | |
| 1888 | try testCanonical( | |
| 1889 | \\comptime { | |
| 1890 | \\ if (sr > n_uword_bits - 1) // d > r | |
| 1891 | \\ return 0; | |
| 1892 | \\} | |
| 1893 | \\ | |
| 1894 | ); | |
| 1895 | } | |
| 1896 | ||
| 1897 | test "zig fmt: same-line comment on comptime expression" { | |
| 1898 | try testCanonical( | |
| 1899 | \\test "" { | |
| 1900 | \\ comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt | |
| 1901 | \\} | |
| 1902 | \\ | |
| 1903 | ); | |
| 1904 | } | |
| 1905 | ||
| 1906 | test "zig fmt: switch with empty body" { | |
| 1907 | try testCanonical( | |
| 1908 | \\test "" { | |
| 1909 | \\ foo() catch |err| switch (err) {}; | |
| 1910 | \\} | |
| 1911 | \\ | |
| 1912 | ); | |
| 1913 | } | |
| 1914 | ||
| 1915 | test "zig fmt: line comments in struct initializer" { | |
| 1916 | try testCanonical( | |
| 1917 | \\fn foo() void { | |
| 1918 | \\ return Self{ | |
| 1919 | \\ .a = b, | |
| 1920 | \\ | |
| 1921 | \\ // Initialize these two fields to buffer_size so that | |
| 1922 | \\ // in `readFn` we treat the state as being able to read | |
| 1923 | \\ .start_index = buffer_size, | |
| 1924 | \\ .end_index = buffer_size, | |
| 1925 | \\ | |
| 1926 | \\ // middle | |
| 1927 | \\ | |
| 1928 | \\ .a = b, | |
| 1929 | \\ | |
| 1930 | \\ // end | |
| 1931 | \\ }; | |
| 1932 | \\} | |
| 1933 | \\ | |
| 1934 | ); | |
| 1935 | } | |
| 1936 | ||
| 1937 | test "zig fmt: first line comment in struct initializer" { | |
| 1938 | try testCanonical( | |
| 1939 | \\pub fn acquire(self: *Self) HeldLock { | |
| 1940 | \\ return HeldLock{ | |
| 1941 | \\ // guaranteed allocation elision | |
| 1942 | \\ .held = self.lock.acquire(), | |
| 1943 | \\ .value = &self.private_data, | |
| 1944 | \\ }; | |
| 1945 | \\} | |
| 1946 | \\ | |
| 1947 | ); | |
| 1948 | } | |
| 1949 | ||
| 1950 | test "zig fmt: doc comments before struct field" { | |
| 1951 | try testCanonical( | |
| 1952 | \\pub const Allocator = struct { | |
| 1953 | \\ /// Allocate byte_count bytes and return them in a slice, with the | |
| 1954 | \\ /// slice's pointer aligned at least to alignment bytes. | |
| 1955 | \\ allocFn: fn () void, | |
| 1956 | \\}; | |
| 1957 | \\ | |
| 1958 | ); | |
| 1959 | } | |
| 1960 | ||
| 1961 | test "zig fmt: error set declaration" { | |
| 1962 | try testCanonical( | |
| 1963 | \\const E = error{ | |
| 1964 | \\ A, | |
| 1965 | \\ B, | |
| 1966 | \\ | |
| 1967 | \\ C, | |
| 1968 | \\}; | |
| 1969 | \\ | |
| 1970 | \\const Error = error{ | |
| 1971 | \\ /// no more memory | |
| 1972 | \\ OutOfMemory, | |
| 1973 | \\}; | |
| 1974 | \\ | |
| 1975 | \\const Error = error{ | |
| 1976 | \\ /// no more memory | |
| 1977 | \\ OutOfMemory, | |
| 1978 | \\ | |
| 1979 | \\ /// another | |
| 1980 | \\ Another, | |
| 1981 | \\ | |
| 1982 | \\ // end | |
| 1983 | \\}; | |
| 1984 | \\ | |
| 1985 | \\const Error = error{OutOfMemory}; | |
| 1986 | \\const Error = error{}; | |
| 1987 | \\ | |
| 1988 | \\const Error = error{ OutOfMemory, OutOfTime }; | |
| 1989 | \\ | |
| 1990 | ); | |
| 1991 | } | |
| 1992 | ||
| 1993 | test "zig fmt: union(enum(u32)) with assigned enum values" { | |
| 1994 | try testCanonical( | |
| 1995 | \\const MultipleChoice = union(enum(u32)) { | |
| 1996 | \\ A = 20, | |
| 1997 | \\ B = 40, | |
| 1998 | \\ C = 60, | |
| 1999 | \\ D = 1000, | |
| 2000 | \\}; | |
| 2001 | \\ | |
| 2002 | ); | |
| 2003 | } | |
| 2004 | ||
| 2005 | test "zig fmt: resume from suspend block" { | |
| 2006 | try testCanonical( | |
| 2007 | \\fn foo() void { | |
| 2008 | \\ suspend { | |
| 2009 | \\ resume @frame(); | |
| 2010 | \\ } | |
| 2011 | \\} | |
| 2012 | \\ | |
| 2013 | ); | |
| 2014 | } | |
| 2015 | ||
| 2016 | test "zig fmt: comments before error set decl" { | |
| 2017 | try testCanonical( | |
| 2018 | \\const UnexpectedError = error{ | |
| 2019 | \\ /// The Operating System returned an undocumented error code. | |
| 2020 | \\ Unexpected, | |
| 2021 | \\ // another | |
| 2022 | \\ Another, | |
| 2023 | \\ | |
| 2024 | \\ // in between | |
| 2025 | \\ | |
| 2026 | \\ // at end | |
| 2027 | \\}; | |
| 2028 | \\ | |
| 2029 | ); | |
| 2030 | } | |
| 2031 | ||
| 2032 | test "zig fmt: comments before switch prong" { | |
| 2033 | try testCanonical( | |
| 2034 | \\test "" { | |
| 2035 | \\ switch (err) { | |
| 2036 | \\ error.PathAlreadyExists => continue, | |
| 2037 | \\ | |
| 2038 | \\ // comment 1 | |
| 2039 | \\ | |
| 2040 | \\ // comment 2 | |
| 2041 | \\ else => return err, | |
| 2042 | \\ // at end | |
| 2043 | \\ } | |
| 2044 | \\} | |
| 2045 | \\ | |
| 2046 | ); | |
| 2047 | } | |
| 2048 | ||
| 2049 | test "zig fmt: comments before var decl in struct" { | |
| 2050 | try testCanonical( | |
| 2051 | \\pub const vfs_cap_data = extern struct { | |
| 2052 | \\ // All of these are mandated as little endian | |
| 2053 | \\ // when on disk. | |
| 2054 | \\ const Data = struct { | |
| 2055 | \\ permitted: u32, | |
| 2056 | \\ inheritable: u32, | |
| 2057 | \\ }; | |
| 2058 | \\ | |
| 2059 | \\ // in between | |
| 2060 | \\ | |
| 2061 | \\ /// All of these are mandated as little endian | |
| 2062 | \\ /// when on disk. | |
| 2063 | \\ const Data = struct { | |
| 2064 | \\ permitted: u32, | |
| 2065 | \\ inheritable: u32, | |
| 2066 | \\ }; | |
| 2067 | \\ | |
| 2068 | \\ // at end | |
| 2069 | \\}; | |
| 2070 | \\ | |
| 2071 | ); | |
| 2072 | } | |
| 2073 | ||
| 2074 | test "zig fmt: array literal with 1 item on 1 line" { | |
| 2075 | try testCanonical( | |
| 2076 | \\var s = []const u64{0} ** 25; | |
| 2077 | \\ | |
| 2078 | ); | |
| 2079 | } | |
| 2080 | ||
| 2081 | test "zig fmt: comments before global variables" { | |
| 2082 | try testCanonical( | |
| 2083 | \\/// Foo copies keys and values before they go into the map, and | |
| 2084 | \\/// frees them when they get removed. | |
| 2085 | \\pub const Foo = struct {}; | |
| 2086 | \\ | |
| 2087 | ); | |
| 2088 | } | |
| 2089 | ||
| 2090 | test "zig fmt: comments in statements" { | |
| 2091 | try testCanonical( | |
| 2092 | \\test "std" { | |
| 2093 | \\ // statement comment | |
| 2094 | \\ _ = @import("foo/bar.zig"); | |
| 2095 | \\ | |
| 2096 | \\ // middle | |
| 2097 | \\ // middle2 | |
| 2098 | \\ | |
| 2099 | \\ // end | |
| 2100 | \\} | |
| 2101 | \\ | |
| 2102 | ); | |
| 2103 | } | |
| 2104 | ||
| 2105 | test "zig fmt: comments before test decl" { | |
| 2106 | try testCanonical( | |
| 2107 | \\/// top level doc comment | |
| 2108 | \\test "hi" {} | |
| 2109 | \\ | |
| 2110 | \\// top level normal comment | |
| 2111 | \\test "hi" {} | |
| 2112 | \\ | |
| 2113 | \\// middle | |
| 2114 | \\ | |
| 2115 | \\// end | |
| 2116 | \\ | |
| 2117 | ); | |
| 2118 | } | |
| 2119 | ||
| 2120 | test "zig fmt: preserve spacing" { | |
| 2121 | try testCanonical( | |
| 2122 | \\const std = @import("std"); | |
| 2123 | \\ | |
| 2124 | \\pub fn main() !void { | |
| 2125 | \\ var stdout_file = std.io.getStdOut; | |
| 2126 | \\ var stdout_file = std.io.getStdOut; | |
| 2127 | \\ | |
| 2128 | \\ var stdout_file = std.io.getStdOut; | |
| 2129 | \\ var stdout_file = std.io.getStdOut; | |
| 2130 | \\} | |
| 2131 | \\ | |
| 2132 | ); | |
| 2133 | } | |
| 2134 | ||
| 2135 | test "zig fmt: return types" { | |
| 2136 | try testCanonical( | |
| 2137 | \\pub fn main() !void {} | |
| 2138 | \\pub fn main() anytype {} | |
| 2139 | \\pub fn main() i32 {} | |
| 2140 | \\ | |
| 2141 | ); | |
| 2142 | } | |
| 2143 | ||
| 2144 | test "zig fmt: imports" { | |
| 2145 | try testCanonical( | |
| 2146 | \\const std = @import("std"); | |
| 2147 | \\const std = @import(); | |
| 2148 | \\ | |
| 2149 | ); | |
| 2150 | } | |
| 2151 | ||
| 2152 | test "zig fmt: global declarations" { | |
| 2153 | try testCanonical( | |
| 2154 | \\const a = b; | |
| 2155 | \\pub const a = b; | |
| 2156 | \\var a = b; | |
| 2157 | \\pub var a = b; | |
| 2158 | \\const a: i32 = b; | |
| 2159 | \\pub const a: i32 = b; | |
| 2160 | \\var a: i32 = b; | |
| 2161 | \\pub var a: i32 = b; | |
| 2162 | \\extern const a: i32 = b; | |
| 2163 | \\pub extern const a: i32 = b; | |
| 2164 | \\extern var a: i32 = b; | |
| 2165 | \\pub extern var a: i32 = b; | |
| 2166 | \\extern "a" const a: i32 = b; | |
| 2167 | \\pub extern "a" const a: i32 = b; | |
| 2168 | \\extern "a" var a: i32 = b; | |
| 2169 | \\pub extern "a" var a: i32 = b; | |
| 2170 | \\ | |
| 2171 | ); | |
| 2172 | } | |
| 2173 | ||
| 2174 | test "zig fmt: extern declaration" { | |
| 2175 | try testCanonical( | |
| 2176 | \\extern var foo: c_int; | |
| 2177 | \\ | |
| 2178 | ); | |
| 2179 | } | |
| 2180 | ||
| 2181 | test "zig fmt: alignment" { | |
| 2182 | try testCanonical( | |
| 2183 | \\var foo: c_int align(1); | |
| 2184 | \\ | |
| 2185 | ); | |
| 2186 | } | |
| 2187 | ||
| 2188 | test "zig fmt: C main" { | |
| 2189 | try testCanonical( | |
| 2190 | \\fn main(argc: c_int, argv: **u8) c_int { | |
| 2191 | \\ const a = b; | |
| 2192 | \\} | |
| 2193 | \\ | |
| 2194 | ); | |
| 2195 | } | |
| 2196 | ||
| 2197 | test "zig fmt: return" { | |
| 2198 | try testCanonical( | |
| 2199 | \\fn foo(argc: c_int, argv: **u8) c_int { | |
| 2200 | \\ return 0; | |
| 2201 | \\} | |
| 2202 | \\ | |
| 2203 | \\fn bar() void { | |
| 2204 | \\ return; | |
| 2205 | \\} | |
| 2206 | \\ | |
| 2207 | ); | |
| 2208 | } | |
| 2209 | ||
| 2210 | test "zig fmt: pointer attributes" { | |
| 2211 | try testCanonical( | |
| 2212 | \\extern fn f1(s: *align(*u8) u8) c_int; | |
| 2213 | \\extern fn f2(s: **align(1) *const *volatile u8) c_int; | |
| 2214 | \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; | |
| 2215 | \\extern fn f4(s: *align(1) const volatile u8) c_int; | |
| 2216 | \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; | |
| 2217 | \\ | |
| 2218 | ); | |
| 2219 | } | |
| 2220 | ||
| 2221 | test "zig fmt: slice attributes" { | |
| 2222 | try testCanonical( | |
| 2223 | \\extern fn f1(s: *align(*u8) u8) c_int; | |
| 2224 | \\extern fn f2(s: **align(1) *const *volatile u8) c_int; | |
| 2225 | \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; | |
| 2226 | \\extern fn f4(s: *align(1) const volatile u8) c_int; | |
| 2227 | \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; | |
| 2228 | \\ | |
| 2229 | ); | |
| 2230 | } | |
| 2231 | ||
| 2232 | test "zig fmt: test declaration" { | |
| 2233 | try testCanonical( | |
| 2234 | \\test "test name" { | |
| 2235 | \\ const a = 1; | |
| 2236 | \\ var b = 1; | |
| 2237 | \\} | |
| 2238 | \\ | |
| 2239 | ); | |
| 2240 | } | |
| 2241 | ||
| 2242 | test "zig fmt: infix operators" { | |
| 2243 | try testCanonical( | |
| 2244 | \\test "infix operators" { | |
| 2245 | \\ var i = undefined; | |
| 2246 | \\ i = 2; | |
| 2247 | \\ i *= 2; | |
| 2248 | \\ i |= 2; | |
| 2249 | \\ i ^= 2; | |
| 2250 | \\ i <<= 2; | |
| 2251 | \\ i >>= 2; | |
| 2252 | \\ i &= 2; | |
| 2253 | \\ i *= 2; | |
| 2254 | \\ i *%= 2; | |
| 2255 | \\ i -= 2; | |
| 2256 | \\ i -%= 2; | |
| 2257 | \\ i += 2; | |
| 2258 | \\ i +%= 2; | |
| 2259 | \\ i /= 2; | |
| 2260 | \\ i %= 2; | |
| 2261 | \\ _ = i == i; | |
| 2262 | \\ _ = i != i; | |
| 2263 | \\ _ = i != i; | |
| 2264 | \\ _ = i.i; | |
| 2265 | \\ _ = i || i; | |
| 2266 | \\ _ = i!i; | |
| 2267 | \\ _ = i ** i; | |
| 2268 | \\ _ = i ++ i; | |
| 2269 | \\ _ = i orelse i; | |
| 2270 | \\ _ = i % i; | |
| 2271 | \\ _ = i / i; | |
| 2272 | \\ _ = i *% i; | |
| 2273 | \\ _ = i * i; | |
| 2274 | \\ _ = i -% i; | |
| 2275 | \\ _ = i - i; | |
| 2276 | \\ _ = i +% i; | |
| 2277 | \\ _ = i + i; | |
| 2278 | \\ _ = i << i; | |
| 2279 | \\ _ = i >> i; | |
| 2280 | \\ _ = i & i; | |
| 2281 | \\ _ = i ^ i; | |
| 2282 | \\ _ = i | i; | |
| 2283 | \\ _ = i >= i; | |
| 2284 | \\ _ = i <= i; | |
| 2285 | \\ _ = i > i; | |
| 2286 | \\ _ = i < i; | |
| 2287 | \\ _ = i and i; | |
| 2288 | \\ _ = i or i; | |
| 2289 | \\} | |
| 2290 | \\ | |
| 2291 | ); | |
| 2292 | } | |
| 2293 | ||
| 2294 | test "zig fmt: precedence" { | |
| 2295 | try testCanonical( | |
| 2296 | \\test "precedence" { | |
| 2297 | \\ a!b(); | |
| 2298 | \\ (a!b)(); | |
| 2299 | \\ !a!b; | |
| 2300 | \\ !(a!b); | |
| 2301 | \\ !a{}; | |
| 2302 | \\ !(a{}); | |
| 2303 | \\ a + b{}; | |
| 2304 | \\ (a + b){}; | |
| 2305 | \\ a << b + c; | |
| 2306 | \\ (a << b) + c; | |
| 2307 | \\ a & b << c; | |
| 2308 | \\ (a & b) << c; | |
| 2309 | \\ a ^ b & c; | |
| 2310 | \\ (a ^ b) & c; | |
| 2311 | \\ a | b ^ c; | |
| 2312 | \\ (a | b) ^ c; | |
| 2313 | \\ a == b | c; | |
| 2314 | \\ (a == b) | c; | |
| 2315 | \\ a and b == c; | |
| 2316 | \\ (a and b) == c; | |
| 2317 | \\ a or b and c; | |
| 2318 | \\ (a or b) and c; | |
| 2319 | \\ (a or b) and c; | |
| 2320 | \\} | |
| 2321 | \\ | |
| 2322 | ); | |
| 2323 | } | |
| 2324 | ||
| 2325 | test "zig fmt: prefix operators" { | |
| 2326 | try testCanonical( | |
| 2327 | \\test "prefix operators" { | |
| 2328 | \\ try return --%~!&0; | |
| 2329 | \\} | |
| 2330 | \\ | |
| 2331 | ); | |
| 2332 | } | |
| 2333 | ||
| 2334 | test "zig fmt: call expression" { | |
| 2335 | try testCanonical( | |
| 2336 | \\test "test calls" { | |
| 2337 | \\ a(); | |
| 2338 | \\ a(1); | |
| 2339 | \\ a(1, 2); | |
| 2340 | \\ a(1, 2) + a(1, 2); | |
| 2341 | \\} | |
| 2342 | \\ | |
| 2343 | ); | |
| 2344 | } | |
| 2345 | ||
| 2346 | test "zig fmt: anytype type" { | |
| 2347 | try testCanonical( | |
| 2348 | \\fn print(args: anytype) anytype {} | |
| 2349 | \\ | |
| 2350 | ); | |
| 2351 | } | |
| 2352 | ||
| 2353 | test "zig fmt: functions" { | |
| 2354 | try testCanonical( | |
| 2355 | \\extern fn puts(s: *const u8) c_int; | |
| 2356 | \\extern "c" fn puts(s: *const u8) c_int; | |
| 2357 | \\export fn puts(s: *const u8) c_int; | |
| 2358 | \\inline fn puts(s: *const u8) c_int; | |
| 2359 | \\noinline fn puts(s: *const u8) c_int; | |
| 2360 | \\pub extern fn puts(s: *const u8) c_int; | |
| 2361 | \\pub extern "c" fn puts(s: *const u8) c_int; | |
| 2362 | \\pub export fn puts(s: *const u8) c_int; | |
| 2363 | \\pub inline fn puts(s: *const u8) c_int; | |
| 2364 | \\pub noinline fn puts(s: *const u8) c_int; | |
| 2365 | \\pub extern fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2366 | \\pub extern "c" fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2367 | \\pub export fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2368 | \\pub inline fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2369 | \\pub noinline fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2370 | \\ | |
| 2371 | ); | |
| 2372 | } | |
| 2373 | ||
| 2374 | test "zig fmt: multiline string" { | |
| 2375 | try testCanonical( | |
| 2376 | \\test "" { | |
| 2377 | \\ const s1 = | |
| 2378 | \\ \\one | |
| 2379 | \\ \\two) | |
| 2380 | \\ \\three | |
| 2381 | \\ ; | |
| 2382 | \\ const s3 = // hi | |
| 2383 | \\ \\one | |
| 2384 | \\ \\two) | |
| 2385 | \\ \\three | |
| 2386 | \\ ; | |
| 2387 | \\} | |
| 2388 | \\ | |
| 2389 | ); | |
| 2390 | } | |
| 2391 | ||
| 2392 | test "zig fmt: values" { | |
| 2393 | try testCanonical( | |
| 2394 | \\test "values" { | |
| 2395 | \\ 1; | |
| 2396 | \\ 1.0; | |
| 2397 | \\ "string"; | |
| 2398 | \\ 'c'; | |
| 2399 | \\ true; | |
| 2400 | \\ false; | |
| 2401 | \\ null; | |
| 2402 | \\ undefined; | |
| 2403 | \\ anyerror; | |
| 2404 | \\ this; | |
| 2405 | \\ unreachable; | |
| 2406 | \\} | |
| 2407 | \\ | |
| 2408 | ); | |
| 2409 | } | |
| 2410 | ||
| 2411 | test "zig fmt: indexing" { | |
| 2412 | try testCanonical( | |
| 2413 | \\test "test index" { | |
| 2414 | \\ a[0]; | |
| 2415 | \\ a[0 + 5]; | |
| 2416 | \\ a[0..]; | |
| 2417 | \\ a[0..5]; | |
| 2418 | \\ a[a[0]]; | |
| 2419 | \\ a[a[0..]]; | |
| 2420 | \\ a[a[0..5]]; | |
| 2421 | \\ a[a[0]..]; | |
| 2422 | \\ a[a[0..5]..]; | |
| 2423 | \\ a[a[0]..a[0]]; | |
| 2424 | \\ a[a[0..5]..a[0]]; | |
| 2425 | \\ a[a[0..5]..a[0..5]]; | |
| 2426 | \\} | |
| 2427 | \\ | |
| 2428 | ); | |
| 2429 | } | |
| 2430 | ||
| 2431 | test "zig fmt: struct declaration" { | |
| 2432 | try testCanonical( | |
| 2433 | \\const S = struct { | |
| 2434 | \\ const Self = @This(); | |
| 2435 | \\ f1: u8, | |
| 2436 | \\ f3: u8, | |
| 2437 | \\ | |
| 2438 | \\ f2: u8, | |
| 2439 | \\ | |
| 2440 | \\ fn method(self: *Self) Self { | |
| 2441 | \\ return self.*; | |
| 2442 | \\ } | |
| 2443 | \\}; | |
| 2444 | \\ | |
| 2445 | \\const Ps = packed struct { | |
| 2446 | \\ a: u8, | |
| 2447 | \\ b: u8, | |
| 2448 | \\ | |
| 2449 | \\ c: u8, | |
| 2450 | \\}; | |
| 2451 | \\ | |
| 2452 | \\const Es = extern struct { | |
| 2453 | \\ a: u8, | |
| 2454 | \\ b: u8, | |
| 2455 | \\ | |
| 2456 | \\ c: u8, | |
| 2457 | \\}; | |
| 2458 | \\ | |
| 2459 | ); | |
| 2460 | } | |
| 2461 | ||
| 2462 | test "zig fmt: enum declaration" { | |
| 2463 | try testCanonical( | |
| 2464 | \\const E = enum { | |
| 2465 | \\ Ok, | |
| 2466 | \\ SomethingElse = 0, | |
| 2467 | \\}; | |
| 2468 | \\ | |
| 2469 | \\const E2 = enum(u8) { | |
| 2470 | \\ Ok, | |
| 2471 | \\ SomethingElse = 255, | |
| 2472 | \\ SomethingThird, | |
| 2473 | \\}; | |
| 2474 | \\ | |
| 2475 | \\const Ee = extern enum { | |
| 2476 | \\ Ok, | |
| 2477 | \\ SomethingElse, | |
| 2478 | \\ SomethingThird, | |
| 2479 | \\}; | |
| 2480 | \\ | |
| 2481 | \\const Ep = packed enum { | |
| 2482 | \\ Ok, | |
| 2483 | \\ SomethingElse, | |
| 2484 | \\ SomethingThird, | |
| 2485 | \\}; | |
| 2486 | \\ | |
| 2487 | ); | |
| 2488 | } | |
| 2489 | ||
| 2490 | test "zig fmt: union declaration" { | |
| 2491 | try testCanonical( | |
| 2492 | \\const U = union { | |
| 2493 | \\ Int: u8, | |
| 2494 | \\ Float: f32, | |
| 2495 | \\ None, | |
| 2496 | \\ Bool: bool, | |
| 2497 | \\}; | |
| 2498 | \\ | |
| 2499 | \\const Ue = union(enum) { | |
| 2500 | \\ Int: u8, | |
| 2501 | \\ Float: f32, | |
| 2502 | \\ None, | |
| 2503 | \\ Bool: bool, | |
| 2504 | \\}; | |
| 2505 | \\ | |
| 2506 | \\const E = enum { | |
| 2507 | \\ Int, | |
| 2508 | \\ Float, | |
| 2509 | \\ None, | |
| 2510 | \\ Bool, | |
| 2511 | \\}; | |
| 2512 | \\ | |
| 2513 | \\const Ue2 = union(E) { | |
| 2514 | \\ Int: u8, | |
| 2515 | \\ Float: f32, | |
| 2516 | \\ None, | |
| 2517 | \\ Bool: bool, | |
| 2518 | \\}; | |
| 2519 | \\ | |
| 2520 | \\const Eu = extern union { | |
| 2521 | \\ Int: u8, | |
| 2522 | \\ Float: f32, | |
| 2523 | \\ None, | |
| 2524 | \\ Bool: bool, | |
| 2525 | \\}; | |
| 2526 | \\ | |
| 2527 | ); | |
| 2528 | } | |
| 2529 | ||
| 2530 | test "zig fmt: arrays" { | |
| 2531 | try testCanonical( | |
| 2532 | \\test "test array" { | |
| 2533 | \\ const a: [2]u8 = [2]u8{ | |
| 2534 | \\ 1, | |
| 2535 | \\ 2, | |
| 2536 | \\ }; | |
| 2537 | \\ const a: [2]u8 = []u8{ | |
| 2538 | \\ 1, | |
| 2539 | \\ 2, | |
| 2540 | \\ }; | |
| 2541 | \\ const a: [0]u8 = []u8{}; | |
| 2542 | \\ const x: [4:0]u8 = undefined; | |
| 2543 | \\} | |
| 2544 | \\ | |
| 2545 | ); | |
| 2546 | } | |
| 2547 | ||
| 2548 | test "zig fmt: container initializers" { | |
| 2549 | try testCanonical( | |
| 2550 | \\const a0 = []u8{}; | |
| 2551 | \\const a1 = []u8{1}; | |
| 2552 | \\const a2 = []u8{ | |
| 2553 | \\ 1, | |
| 2554 | \\ 2, | |
| 2555 | \\ 3, | |
| 2556 | \\ 4, | |
| 2557 | \\}; | |
| 2558 | \\const s0 = S{}; | |
| 2559 | \\const s1 = S{ .a = 1 }; | |
| 2560 | \\const s2 = S{ | |
| 2561 | \\ .a = 1, | |
| 2562 | \\ .b = 2, | |
| 2563 | \\}; | |
| 2564 | \\ | |
| 2565 | ); | |
| 2566 | } | |
| 2567 | ||
| 2568 | test "zig fmt: catch" { | |
| 2569 | try testCanonical( | |
| 2570 | \\test "catch" { | |
| 2571 | \\ const a: anyerror!u8 = 0; | |
| 2572 | \\ _ = a catch return; | |
| 2573 | \\ _ = a catch |err| return; | |
| 2574 | \\} | |
| 2575 | \\ | |
| 2576 | ); | |
| 2577 | } | |
| 2578 | ||
| 2579 | test "zig fmt: blocks" { | |
| 2580 | try testCanonical( | |
| 2581 | \\test "blocks" { | |
| 2582 | \\ { | |
| 2583 | \\ const a = 0; | |
| 2584 | \\ const b = 0; | |
| 2585 | \\ } | |
| 2586 | \\ | |
| 2587 | \\ blk: { | |
| 2588 | \\ const a = 0; | |
| 2589 | \\ const b = 0; | |
| 2590 | \\ } | |
| 2591 | \\ | |
| 2592 | \\ const r = blk: { | |
| 2593 | \\ const a = 0; | |
| 2594 | \\ const b = 0; | |
| 2595 | \\ }; | |
| 2596 | \\} | |
| 2597 | \\ | |
| 2598 | ); | |
| 2599 | } | |
| 2600 | ||
| 2601 | test "zig fmt: switch" { | |
| 2602 | try testCanonical( | |
| 2603 | \\test "switch" { | |
| 2604 | \\ switch (0) { | |
| 2605 | \\ 0 => {}, | |
| 2606 | \\ 1 => unreachable, | |
| 2607 | \\ 2, 3 => {}, | |
| 2608 | \\ 4...7 => {}, | |
| 2609 | \\ 1 + 4 * 3 + 22 => {}, | |
| 2610 | \\ else => { | |
| 2611 | \\ const a = 1; | |
| 2612 | \\ const b = a; | |
| 2613 | \\ }, | |
| 2614 | \\ } | |
| 2615 | \\ | |
| 2616 | \\ const res = switch (0) { | |
| 2617 | \\ 0 => 0, | |
| 2618 | \\ 1 => 2, | |
| 2619 | \\ 1 => a = 4, | |
| 2620 | \\ else => 4, | |
| 2621 | \\ }; | |
| 2622 | \\ | |
| 2623 | \\ const Union = union(enum) { | |
| 2624 | \\ Int: i64, | |
| 2625 | \\ Float: f64, | |
| 2626 | \\ }; | |
| 2627 | \\ | |
| 2628 | \\ switch (u) { | |
| 2629 | \\ Union.Int => |int| {}, | |
| 2630 | \\ Union.Float => |*float| unreachable, | |
| 2631 | \\ } | |
| 2632 | \\} | |
| 2633 | \\ | |
| 2634 | ); | |
| 2635 | } | |
| 2636 | ||
| 2637 | test "zig fmt: while" { | |
| 2638 | try testCanonical( | |
| 2639 | \\test "while" { | |
| 2640 | \\ while (10 < 1) unreachable; | |
| 2641 | \\ | |
| 2642 | \\ while (10 < 1) unreachable else unreachable; | |
| 2643 | \\ | |
| 2644 | \\ while (10 < 1) { | |
| 2645 | \\ unreachable; | |
| 2646 | \\ } | |
| 2647 | \\ | |
| 2648 | \\ while (10 < 1) | |
| 2649 | \\ unreachable; | |
| 2650 | \\ | |
| 2651 | \\ var i: usize = 0; | |
| 2652 | \\ while (i < 10) : (i += 1) { | |
| 2653 | \\ continue; | |
| 2654 | \\ } | |
| 2655 | \\ | |
| 2656 | \\ i = 0; | |
| 2657 | \\ while (i < 10) : (i += 1) | |
| 2658 | \\ continue; | |
| 2659 | \\ | |
| 2660 | \\ i = 0; | |
| 2661 | \\ var j: usize = 0; | |
| 2662 | \\ while (i < 10) : ({ | |
| 2663 | \\ i += 1; | |
| 2664 | \\ j += 1; | |
| 2665 | \\ }) { | |
| 2666 | \\ continue; | |
| 2667 | \\ } | |
| 2668 | \\ | |
| 2669 | \\ var a: ?u8 = 2; | |
| 2670 | \\ while (a) |v| : (a = null) { | |
| 2671 | \\ continue; | |
| 2672 | \\ } | |
| 2673 | \\ | |
| 2674 | \\ while (a) |v| : (a = null) | |
| 2675 | \\ unreachable; | |
| 2676 | \\ | |
| 2677 | \\ label: while (10 < 0) { | |
| 2678 | \\ unreachable; | |
| 2679 | \\ } | |
| 2680 | \\ | |
| 2681 | \\ const res = while (0 < 10) { | |
| 2682 | \\ break 7; | |
| 2683 | \\ } else { | |
| 2684 | \\ unreachable; | |
| 2685 | \\ }; | |
| 2686 | \\ | |
| 2687 | \\ const res = while (0 < 10) | |
| 2688 | \\ break 7 | |
| 2689 | \\ else | |
| 2690 | \\ unreachable; | |
| 2691 | \\ | |
| 2692 | \\ var a: anyerror!u8 = 0; | |
| 2693 | \\ while (a) |v| { | |
| 2694 | \\ a = error.Err; | |
| 2695 | \\ } else |err| { | |
| 2696 | \\ i = 1; | |
| 2697 | \\ } | |
| 2698 | \\ | |
| 2699 | \\ comptime var k: usize = 0; | |
| 2700 | \\ inline while (i < 10) : (i += 1) | |
| 2701 | \\ j += 2; | |
| 2702 | \\} | |
| 2703 | \\ | |
| 2704 | ); | |
| 2705 | } | |
| 2706 | ||
| 2707 | test "zig fmt: for" { | |
| 2708 | try testCanonical( | |
| 2709 | \\test "for" { | |
| 2710 | \\ for (a) |v| { | |
| 2711 | \\ continue; | |
| 2712 | \\ } | |
| 2713 | \\ | |
| 2714 | \\ for (a) |v| continue; | |
| 2715 | \\ | |
| 2716 | \\ for (a) |v| continue else return; | |
| 2717 | \\ | |
| 2718 | \\ for (a) |v| { | |
| 2719 | \\ continue; | |
| 2720 | \\ } else return; | |
| 2721 | \\ | |
| 2722 | \\ for (a) |v| continue else { | |
| 2723 | \\ return; | |
| 2724 | \\ } | |
| 2725 | \\ | |
| 2726 | \\ for (a) |v| | |
| 2727 | \\ continue | |
| 2728 | \\ else | |
| 2729 | \\ return; | |
| 2730 | \\ | |
| 2731 | \\ for (a) |v| | |
| 2732 | \\ continue; | |
| 2733 | \\ | |
| 2734 | \\ for (a) |*v| | |
| 2735 | \\ continue; | |
| 2736 | \\ | |
| 2737 | \\ for (a) |v, i| { | |
| 2738 | \\ continue; | |
| 2739 | \\ } | |
| 2740 | \\ | |
| 2741 | \\ for (a) |v, i| | |
| 2742 | \\ continue; | |
| 2743 | \\ | |
| 2744 | \\ for (a) |b| switch (b) { | |
| 2745 | \\ c => {}, | |
| 2746 | \\ d => {}, | |
| 2747 | \\ }; | |
| 2748 | \\ | |
| 2749 | \\ for (a) |b| | |
| 2750 | \\ switch (b) { | |
| 2751 | \\ c => {}, | |
| 2752 | \\ d => {}, | |
| 2753 | \\ }; | |
| 2754 | \\ | |
| 2755 | \\ const res = for (a) |v, i| { | |
| 2756 | \\ break v; | |
| 2757 | \\ } else { | |
| 2758 | \\ unreachable; | |
| 2759 | \\ }; | |
| 2760 | \\ | |
| 2761 | \\ var num: usize = 0; | |
| 2762 | \\ inline for (a) |v, i| { | |
| 2763 | \\ num += v; | |
| 2764 | \\ num += i; | |
| 2765 | \\ } | |
| 2766 | \\} | |
| 2767 | \\ | |
| 2768 | ); | |
| 2769 | ||
| 2770 | try testTransform( | |
| 2771 | \\test "fix for" { | |
| 2772 | \\ for (a) |x| | |
| 2773 | \\ f(x) else continue; | |
| 2774 | \\} | |
| 2775 | \\ | |
| 2776 | , | |
| 2777 | \\test "fix for" { | |
| 2778 | \\ for (a) |x| | |
| 2779 | \\ f(x) | |
| 2780 | \\ else continue; | |
| 2781 | \\} | |
| 2782 | \\ | |
| 2783 | ); | |
| 2784 | } | |
| 2785 | ||
| 2786 | test "zig fmt: if" { | |
| 2787 | try testCanonical( | |
| 2788 | \\test "if" { | |
| 2789 | \\ if (10 < 0) { | |
| 2790 | \\ unreachable; | |
| 2791 | \\ } | |
| 2792 | \\ | |
| 2793 | \\ if (10 < 0) unreachable; | |
| 2794 | \\ | |
| 2795 | \\ if (10 < 0) { | |
| 2796 | \\ unreachable; | |
| 2797 | \\ } else { | |
| 2798 | \\ const a = 20; | |
| 2799 | \\ } | |
| 2800 | \\ | |
| 2801 | \\ if (10 < 0) { | |
| 2802 | \\ unreachable; | |
| 2803 | \\ } else if (5 < 0) { | |
| 2804 | \\ unreachable; | |
| 2805 | \\ } else { | |
| 2806 | \\ const a = 20; | |
| 2807 | \\ } | |
| 2808 | \\ | |
| 2809 | \\ const is_world_broken = if (10 < 0) true else false; | |
| 2810 | \\ const some_number = 1 + if (10 < 0) 2 else 3; | |
| 2811 | \\ | |
| 2812 | \\ const a: ?u8 = 10; | |
| 2813 | \\ const b: ?u8 = null; | |
| 2814 | \\ if (a) |v| { | |
| 2815 | \\ const some = v; | |
| 2816 | \\ } else if (b) |*v| { | |
| 2817 | \\ unreachable; | |
| 2818 | \\ } else { | |
| 2819 | \\ const some = 10; | |
| 2820 | \\ } | |
| 2821 | \\ | |
| 2822 | \\ const non_null_a = if (a) |v| v else 0; | |
| 2823 | \\ | |
| 2824 | \\ const a_err: anyerror!u8 = 0; | |
| 2825 | \\ if (a_err) |v| { | |
| 2826 | \\ const p = v; | |
| 2827 | \\ } else |err| { | |
| 2828 | \\ unreachable; | |
| 2829 | \\ } | |
| 2830 | \\} | |
| 2831 | \\ | |
| 2832 | ); | |
| 2833 | } | |
| 2834 | ||
| 2835 | test "zig fmt: defer" { | |
| 2836 | try testCanonical( | |
| 2837 | \\test "defer" { | |
| 2838 | \\ var i: usize = 0; | |
| 2839 | \\ defer i = 1; | |
| 2840 | \\ defer { | |
| 2841 | \\ i += 2; | |
| 2842 | \\ i *= i; | |
| 2843 | \\ } | |
| 2844 | \\ | |
| 2845 | \\ errdefer i += 3; | |
| 2846 | \\ errdefer { | |
| 2847 | \\ i += 2; | |
| 2848 | \\ i /= i; | |
| 2849 | \\ } | |
| 2850 | \\} | |
| 2851 | \\ | |
| 2852 | ); | |
| 2853 | } | |
| 2854 | ||
| 2855 | test "zig fmt: comptime" { | |
| 2856 | try testCanonical( | |
| 2857 | \\fn a() u8 { | |
| 2858 | \\ return 5; | |
| 2859 | \\} | |
| 2860 | \\ | |
| 2861 | \\fn b(comptime i: u8) u8 { | |
| 2862 | \\ return i; | |
| 2863 | \\} | |
| 2864 | \\ | |
| 2865 | \\const av = comptime a(); | |
| 2866 | \\const av2 = comptime blk: { | |
| 2867 | \\ var res = a(); | |
| 2868 | \\ res *= b(2); | |
| 2869 | \\ break :blk res; | |
| 2870 | \\}; | |
| 2871 | \\ | |
| 2872 | \\comptime { | |
| 2873 | \\ _ = a(); | |
| 2874 | \\} | |
| 2875 | \\ | |
| 2876 | \\test "comptime" { | |
| 2877 | \\ const av3 = comptime a(); | |
| 2878 | \\ const av4 = comptime blk: { | |
| 2879 | \\ var res = a(); | |
| 2880 | \\ res *= a(); | |
| 2881 | \\ break :blk res; | |
| 2882 | \\ }; | |
| 2883 | \\ | |
| 2884 | \\ comptime var i = 0; | |
| 2885 | \\ comptime { | |
| 2886 | \\ i = a(); | |
| 2887 | \\ i += b(i); | |
| 2888 | \\ } | |
| 2889 | \\} | |
| 2890 | \\ | |
| 2891 | ); | |
| 2892 | } | |
| 2893 | ||
| 2894 | test "zig fmt: fn type" { | |
| 2895 | try testCanonical( | |
| 2896 | \\fn a(i: u8) u8 { | |
| 2897 | \\ return i + 1; | |
| 2898 | \\} | |
| 2899 | \\ | |
| 2900 | \\const a: fn (u8) u8 = undefined; | |
| 2901 | \\const b: fn (u8) callconv(.Naked) u8 = undefined; | |
| 2902 | \\const ap: fn (u8) u8 = a; | |
| 2903 | \\ | |
| 2904 | ); | |
| 2905 | } | |
| 2906 | ||
| 2907 | test "zig fmt: inline asm" { | |
| 2908 | try testCanonical( | |
| 2909 | \\pub fn syscall1(number: usize, arg1: usize) usize { | |
| 2910 | \\ return asm volatile ("syscall" | |
| 2911 | \\ : [ret] "={rax}" (-> usize) | |
| 2912 | \\ : [number] "{rax}" (number), | |
| 2913 | \\ [arg1] "{rdi}" (arg1) | |
| 2914 | \\ : "rcx", "r11" | |
| 2915 | \\ ); | |
| 2916 | \\} | |
| 2917 | \\ | |
| 2918 | ); | |
| 2919 | } | |
| 2920 | ||
| 2921 | test "zig fmt: async functions" { | |
| 2922 | try testCanonical( | |
| 2923 | \\fn simpleAsyncFn() void { | |
| 2924 | \\ const a = async a.b(); | |
| 2925 | \\ x += 1; | |
| 2926 | \\ suspend; | |
| 2927 | \\ x += 1; | |
| 2928 | \\ suspend; | |
| 2929 | \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable; | |
| 2930 | \\ await p; | |
| 2931 | \\} | |
| 2932 | \\ | |
| 2933 | \\test "suspend, resume, await" { | |
| 2934 | \\ const p: anyframe = async testAsyncSeq(); | |
| 2935 | \\ resume p; | |
| 2936 | \\ await p; | |
| 2937 | \\} | |
| 2938 | \\ | |
| 2939 | ); | |
| 2940 | } | |
| 2941 | ||
| 2942 | test "zig fmt: nosuspend" { | |
| 2943 | try testCanonical( | |
| 2944 | \\const a = nosuspend foo(); | |
| 2945 | \\ | |
| 2946 | ); | |
| 2947 | } | |
| 2948 | ||
| 2949 | test "zig fmt: Block after if" { | |
| 2950 | try testCanonical( | |
| 2951 | \\test "Block after if" { | |
| 2952 | \\ if (true) { | |
| 2953 | \\ const a = 0; | |
| 2954 | \\ } | |
| 2955 | \\ | |
| 2956 | \\ { | |
| 2957 | \\ const a = 0; | |
| 2958 | \\ } | |
| 2959 | \\} | |
| 2960 | \\ | |
| 2961 | ); | |
| 2962 | } | |
| 2963 | ||
| 2964 | test "zig fmt: use" { | |
| 2965 | try testCanonical( | |
| 2966 | \\usingnamespace @import("std"); | |
| 2967 | \\pub usingnamespace @import("std"); | |
| 2968 | \\ | |
| 2969 | ); | |
| 2970 | } | |
| 2971 | ||
| 2972 | test "zig fmt: string identifier" { | |
| 2973 | try testCanonical( | |
| 2974 | \\const @"a b" = @"c d".@"e f"; | |
| 2975 | \\fn @"g h"() void {} | |
| 2976 | \\ | |
| 2977 | ); | |
| 2978 | } | |
| 2979 | ||
| 2980 | test "zig fmt: error return" { | |
| 2981 | try testCanonical( | |
| 2982 | \\fn err() anyerror { | |
| 2983 | \\ call(); | |
| 2984 | \\ return error.InvalidArgs; | |
| 2985 | \\} | |
| 2986 | \\ | |
| 2987 | ); | |
| 2988 | } | |
| 2989 | ||
| 2990 | test "zig fmt: comptime block in container" { | |
| 2991 | try testCanonical( | |
| 2992 | \\pub fn container() type { | |
| 2993 | \\ return struct { | |
| 2994 | \\ comptime { | |
| 2995 | \\ if (false) { | |
| 2996 | \\ unreachable; | |
| 2997 | \\ } | |
| 2998 | \\ } | |
| 2999 | \\ }; | |
| 3000 | \\} | |
| 3001 | \\ | |
| 3002 | ); | |
| 3003 | } | |
| 3004 | ||
| 3005 | test "zig fmt: inline asm parameter alignment" { | |
| 3006 | try testCanonical( | |
| 3007 | \\pub fn main() void { | |
| 3008 | \\ asm volatile ( | |
| 3009 | \\ \\ foo | |
| 3010 | \\ \\ bar | |
| 3011 | \\ ); | |
| 3012 | \\ asm volatile ( | |
| 3013 | \\ \\ foo | |
| 3014 | \\ \\ bar | |
| 3015 | \\ : [_] "" (-> usize), | |
| 3016 | \\ [_] "" (-> usize) | |
| 3017 | \\ ); | |
| 3018 | \\ asm volatile ( | |
| 3019 | \\ \\ foo | |
| 3020 | \\ \\ bar | |
| 3021 | \\ : | |
| 3022 | \\ : [_] "" (0), | |
| 3023 | \\ [_] "" (0) | |
| 3024 | \\ ); | |
| 3025 | \\ asm volatile ( | |
| 3026 | \\ \\ foo | |
| 3027 | \\ \\ bar | |
| 3028 | \\ : | |
| 3029 | \\ : | |
| 3030 | \\ : "", "" | |
| 3031 | \\ ); | |
| 3032 | \\ asm volatile ( | |
| 3033 | \\ \\ foo | |
| 3034 | \\ \\ bar | |
| 3035 | \\ : [_] "" (-> usize), | |
| 3036 | \\ [_] "" (-> usize) | |
| 3037 | \\ : [_] "" (0), | |
| 3038 | \\ [_] "" (0) | |
| 3039 | \\ : "", "" | |
| 3040 | \\ ); | |
| 3041 | \\} | |
| 3042 | \\ | |
| 3043 | ); | |
| 3044 | } | |
| 3045 | ||
| 3046 | test "zig fmt: multiline string in array" { | |
| 3047 | try testCanonical( | |
| 3048 | \\const Foo = [][]const u8{ | |
| 3049 | \\ \\aaa | |
| 3050 | \\ , | |
| 3051 | \\ \\bbb | |
| 3052 | \\}; | |
| 3053 | \\ | |
| 3054 | \\fn bar() void { | |
| 3055 | \\ const Foo = [][]const u8{ | |
| 3056 | \\ \\aaa | |
| 3057 | \\ , | |
| 3058 | \\ \\bbb | |
| 3059 | \\ }; | |
| 3060 | \\ const Bar = [][]const u8{ // comment here | |
| 3061 | \\ \\aaa | |
| 3062 | \\ \\ | |
| 3063 | \\ , // and another comment can go here | |
| 3064 | \\ \\bbb | |
| 3065 | \\ }; | |
| 3066 | \\} | |
| 3067 | \\ | |
| 3068 | ); | |
| 3069 | } | |
| 3070 | ||
| 3071 | test "zig fmt: if type expr" { | |
| 3072 | try testCanonical( | |
| 3073 | \\const mycond = true; | |
| 3074 | \\pub fn foo() if (mycond) i32 else void { | |
| 3075 | \\ if (mycond) { | |
| 3076 | \\ return 42; | |
| 3077 | \\ } | |
| 3078 | \\} | |
| 3079 | \\ | |
| 3080 | ); | |
| 3081 | } | |
| 3082 | test "zig fmt: file ends with struct field" { | |
| 3083 | try testCanonical( | |
| 3084 | \\a: bool | |
| 3085 | \\ | |
| 3086 | ); | |
| 3087 | } | |
| 3088 | ||
| 3089 | test "zig fmt: comment after empty comment" { | |
| 3090 | try testTransform( | |
| 3091 | \\const x = true; // | |
| 3092 | \\// | |
| 3093 | \\// | |
| 3094 | \\//a | |
| 3095 | \\ | |
| 3096 | , | |
| 3097 | \\const x = true; | |
| 3098 | \\//a | |
| 3099 | \\ | |
| 3100 | ); | |
| 3101 | } | |
| 3102 | ||
| 3103 | test "zig fmt: line comment in array" { | |
| 3104 | try testTransform( | |
| 3105 | \\test "a" { | |
| 3106 | \\ var arr = [_]u32{ | |
| 3107 | \\ 0 | |
| 3108 | \\ // 1, | |
| 3109 | \\ // 2, | |
| 3110 | \\ }; | |
| 3111 | \\} | |
| 3112 | \\ | |
| 3113 | , | |
| 3114 | \\test "a" { | |
| 3115 | \\ var arr = [_]u32{ | |
| 3116 | \\ 0, // 1, | |
| 3117 | \\ // 2, | |
| 3118 | \\ }; | |
| 3119 | \\} | |
| 3120 | \\ | |
| 3121 | ); | |
| 3122 | try testCanonical( | |
| 3123 | \\test "a" { | |
| 3124 | \\ var arr = [_]u32{ | |
| 3125 | \\ 0, | |
| 3126 | \\ // 1, | |
| 3127 | \\ // 2, | |
| 3128 | \\ }; | |
| 3129 | \\} | |
| 3130 | \\ | |
| 3131 | ); | |
| 3132 | } | |
| 3133 | ||
| 3134 | test "zig fmt: comment after params" { | |
| 3135 | try testTransform( | |
| 3136 | \\fn a( | |
| 3137 | \\ b: u32 | |
| 3138 | \\ // c: u32, | |
| 3139 | \\ // d: u32, | |
| 3140 | \\) void {} | |
| 3141 | \\ | |
| 3142 | , | |
| 3143 | \\fn a( | |
| 3144 | \\ b: u32, // c: u32, | |
| 3145 | \\ // d: u32, | |
| 3146 | \\) void {} | |
| 3147 | \\ | |
| 3148 | ); | |
| 3149 | try testCanonical( | |
| 3150 | \\fn a( | |
| 3151 | \\ b: u32, | |
| 3152 | \\ // c: u32, | |
| 3153 | \\ // d: u32, | |
| 3154 | \\) void {} | |
| 3155 | \\ | |
| 3156 | ); | |
| 3157 | } | |
| 3158 | ||
| 3159 | test "zig fmt: comment in array initializer/access" { | |
| 3160 | try testCanonical( | |
| 3161 | \\test "a" { | |
| 3162 | \\ var a = x{ //aa | |
| 3163 | \\ //bb | |
| 3164 | \\ }; | |
| 3165 | \\ var a = []x{ //aa | |
| 3166 | \\ //bb | |
| 3167 | \\ }; | |
| 3168 | \\ var b = [ //aa | |
| 3169 | \\ _ | |
| 3170 | \\ ]x{ //aa | |
| 3171 | \\ //bb | |
| 3172 | \\ 9, | |
| 3173 | \\ }; | |
| 3174 | \\ var c = b[ //aa | |
| 3175 | \\ 0 | |
| 3176 | \\ ]; | |
| 3177 | \\ var d = [_ | |
| 3178 | \\ //aa | |
| 3179 | \\ ]x{ //aa | |
| 3180 | \\ //bb | |
| 3181 | \\ 9, | |
| 3182 | \\ }; | |
| 3183 | \\ var e = d[0 | |
| 3184 | \\ //aa | |
| 3185 | \\ ]; | |
| 3186 | \\} | |
| 3187 | \\ | |
| 3188 | ); | |
| 3189 | } | |
| 3190 | ||
| 3191 | test "zig fmt: comments at several places in struct init" { | |
| 3192 | try testTransform( | |
| 3193 | \\var bar = Bar{ | |
| 3194 | \\ .x = 10, // test | |
| 3195 | \\ .y = "test" | |
| 3196 | \\ // test | |
| 3197 | \\}; | |
| 3198 | \\ | |
| 3199 | , | |
| 3200 | \\var bar = Bar{ | |
| 3201 | \\ .x = 10, // test | |
| 3202 | \\ .y = "test", // test | |
| 3203 | \\}; | |
| 3204 | \\ | |
| 3205 | ); | |
| 3206 | ||
| 3207 | try testCanonical( | |
| 3208 | \\var bar = Bar{ // test | |
| 3209 | \\ .x = 10, // test | |
| 3210 | \\ .y = "test", | |
| 3211 | \\ // test | |
| 3212 | \\}; | |
| 3213 | \\ | |
| 3214 | ); | |
| 3215 | } | |
| 3216 | ||
| 3217 | test "zig fmt: top level doc comments" { | |
| 3218 | try testCanonical( | |
| 3219 | \\//! tld 1 | |
| 3220 | \\//! tld 2 | |
| 3221 | \\//! tld 3 | |
| 3222 | \\ | |
| 3223 | \\// comment | |
| 3224 | \\ | |
| 3225 | \\/// A doc | |
| 3226 | \\const A = struct { | |
| 3227 | \\ //! A tld 1 | |
| 3228 | \\ //! A tld 2 | |
| 3229 | \\ //! A tld 3 | |
| 3230 | \\}; | |
| 3231 | \\ | |
| 3232 | \\/// B doc | |
| 3233 | \\const B = struct { | |
| 3234 | \\ //! B tld 1 | |
| 3235 | \\ //! B tld 2 | |
| 3236 | \\ //! B tld 3 | |
| 3237 | \\ | |
| 3238 | \\ /// b doc | |
| 3239 | \\ b: u32, | |
| 3240 | \\}; | |
| 3241 | \\ | |
| 3242 | \\/// C doc | |
| 3243 | \\const C = struct { | |
| 3244 | \\ //! C tld 1 | |
| 3245 | \\ //! C tld 2 | |
| 3246 | \\ //! C tld 3 | |
| 3247 | \\ | |
| 3248 | \\ /// c1 doc | |
| 3249 | \\ c1: u32, | |
| 3250 | \\ | |
| 3251 | \\ //! C tld 4 | |
| 3252 | \\ //! C tld 5 | |
| 3253 | \\ //! C tld 6 | |
| 3254 | \\ | |
| 3255 | \\ /// c2 doc | |
| 3256 | \\ c2: u32, | |
| 3257 | \\}; | |
| 3258 | \\ | |
| 3259 | ); | |
| 3260 | try testCanonical( | |
| 3261 | \\//! Top-level documentation. | |
| 3262 | \\ | |
| 3263 | \\/// This is A | |
| 3264 | \\pub const A = usize; | |
| 3265 | \\ | |
| 3266 | ); | |
| 3267 | try testCanonical( | |
| 3268 | \\//! Nothing here | |
| 3269 | \\ | |
| 3270 | ); | |
| 3271 | } | |
| 3272 | ||
| 3273 | test "zig fmt: extern without container keyword returns error" { | |
| 3274 | try testError( | |
| 3275 | \\const container = extern {}; | |
| 3276 | \\ | |
| 3277 | , &[_]Error{ | |
| 3278 | .ExpectedExpr, | |
| 3279 | .ExpectedVarDeclOrFn, | |
| 3280 | }); | |
| 3281 | } | |
| 3282 | ||
| 3283 | test "zig fmt: integer literals with underscore separators" { | |
| 3284 | try testTransform( | |
| 3285 | \\const | |
| 3286 | \\ x = | |
| 3287 | \\ 1_234_567 | |
| 3288 | \\ +(0b0_1-0o7_0+0xff_FF ) + 0_0; | |
| 3289 | , | |
| 3290 | \\const x = | |
| 3291 | \\ 1_234_567 + (0b0_1 - 0o7_0 + 0xff_FF) + 0_0; | |
| 3292 | \\ | |
| 3293 | ); | |
| 3294 | } | |
| 3295 | ||
| 3296 | test "zig fmt: hex literals with underscore separators" { | |
| 3297 | try testTransform( | |
| 3298 | \\pub fn orMask(a: [ 1_000 ]u64, b: [ 1_000] u64) [1_000]u64 { | |
| 3299 | \\ var c: [1_000]u64 = [1]u64{ 0xFFFF_FFFF_FFFF_FFFF}**1_000; | |
| 3300 | \\ for (c [ 0_0 .. ]) |_, i| { | |
| 3301 | \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA; | |
| 3302 | \\ } | |
| 3303 | \\ return c; | |
| 3304 | \\} | |
| 3305 | \\ | |
| 3306 | \\ | |
| 3307 | , | |
| 3308 | \\pub fn orMask(a: [1_000]u64, b: [1_000]u64) [1_000]u64 { | |
| 3309 | \\ var c: [1_000]u64 = [1]u64{0xFFFF_FFFF_FFFF_FFFF} ** 1_000; | |
| 3310 | \\ for (c[0_0..]) |_, i| { | |
| 3311 | \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA; | |
| 3312 | \\ } | |
| 3313 | \\ return c; | |
| 3314 | \\} | |
| 3315 | \\ | |
| 3316 | ); | |
| 3317 | } | |
| 3318 | ||
| 3319 | test "zig fmt: decimal float literals with underscore separators" { | |
| 3320 | try testTransform( | |
| 3321 | \\pub fn main() void { | |
| 3322 | \\ const a:f64=(10.0e-0+(10.e+0))+10_00.00_00e-2+00_00.00_10e+4; | |
| 3323 | \\ const b:f64=010.0--0_10.+0_1_0.0_0+1e2; | |
| 3324 | \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3325 | \\} | |
| 3326 | , | |
| 3327 | \\pub fn main() void { | |
| 3328 | \\ const a: f64 = (10.0e-0 + (10.e+0)) + 10_00.00_00e-2 + 00_00.00_10e+4; | |
| 3329 | \\ const b: f64 = 010.0 - -0_10. + 0_1_0.0_0 + 1e2; | |
| 3330 | \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3331 | \\} | |
| 3332 | \\ | |
| 3333 | ); | |
| 3334 | } | |
| 3335 | ||
| 3336 | test "zig fmt: hexadeciaml float literals with underscore separators" { | |
| 3337 | try testTransform( | |
| 3338 | \\pub fn main() void { | |
| 3339 | \\ const a: f64 = (0x10.0p-0+(0x10.p+0))+0x10_00.00_00p-8+0x00_00.00_10p+16; | |
| 3340 | \\ const b: f64 = 0x0010.0--0x00_10.+0x10.00+0x1p4; | |
| 3341 | \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3342 | \\} | |
| 3343 | , | |
| 3344 | \\pub fn main() void { | |
| 3345 | \\ const a: f64 = (0x10.0p-0 + (0x10.p+0)) + 0x10_00.00_00p-8 + 0x00_00.00_10p+16; | |
| 3346 | \\ const b: f64 = 0x0010.0 - -0x00_10. + 0x10.00 + 0x1p4; | |
| 3347 | \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3348 | \\} | |
| 3349 | \\ | |
| 3350 | ); | |
| 3351 | } | |
| 3352 | ||
| 3353 | test "zig fmt: convert async fn into callconv(.Async)" { | |
| 3354 | try testTransform( | |
| 3355 | \\async fn foo() void {} | |
| 3356 | , | |
| 3357 | \\fn foo() callconv(.Async) void {} | |
| 3358 | \\ | |
| 3359 | ); | |
| 3360 | } | |
| 3361 | ||
| 3362 | test "zig fmt: convert extern fn proto into callconv(.C)" { | |
| 3363 | try testTransform( | |
| 3364 | \\extern fn foo0() void {} | |
| 3365 | \\const foo1 = extern fn () void; | |
| 3366 | , | |
| 3367 | \\extern fn foo0() void {} | |
| 3368 | \\const foo1 = fn () callconv(.C) void; | |
| 3369 | \\ | |
| 3370 | ); | |
| 3371 | } | |
| 3372 | ||
| 3373 | test "zig fmt: C var args" { | |
| 3374 | try testCanonical( | |
| 3375 | \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; | |
| 3376 | \\ | |
| 3377 | ); | |
| 3378 | } | |
| 3379 | ||
| 3380 | test "zig fmt: Only indent multiline string literals in function calls" { | |
| 3381 | try testCanonical( | |
| 3382 | \\test "zig fmt:" { | |
| 3383 | \\ try testTransform( | |
| 3384 | \\ \\const X = struct { | |
| 3385 | \\ \\ foo: i32, bar: i8 }; | |
| 3386 | \\ , | |
| 3387 | \\ \\const X = struct { | |
| 3388 | \\ \\ foo: i32, bar: i8 | |
| 3389 | \\ \\}; | |
| 3390 | \\ \\ | |
| 3391 | \\ ); | |
| 3392 | \\} | |
| 3393 | \\ | |
| 3394 | ); | |
| 3395 | } | |
| 3396 | ||
| 3397 | test "zig fmt: Don't add extra newline after if" { | |
| 3398 | try testCanonical( | |
| 3399 | \\pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { | |
| 3400 | \\ if (cwd().symLink(existing_path, new_path, .{})) { | |
| 3401 | \\ return; | |
| 3402 | \\ } | |
| 3403 | \\} | |
| 3404 | \\ | |
| 3405 | ); | |
| 3406 | } | |
| 3407 | ||
| 3408 | test "zig fmt: comments in ternary ifs" { | |
| 3409 | try testCanonical( | |
| 3410 | \\const x = if (true) { | |
| 3411 | \\ 1; | |
| 3412 | \\} else if (false) | |
| 3413 | \\ // Comment | |
| 3414 | \\ 0; | |
| 3415 | \\const y = if (true) | |
| 3416 | \\ // Comment | |
| 3417 | \\ 1 | |
| 3418 | \\else | |
| 3419 | \\ 0; | |
| 3420 | \\ | |
| 3421 | \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; | |
| 3422 | \\ | |
| 3423 | ); | |
| 3424 | } | |
| 3425 | ||
| 3426 | test "zig fmt: test comments in field access chain" { | |
| 3427 | try testCanonical( | |
| 3428 | \\pub const str = struct { | |
| 3429 | \\ pub const Thing = more.more // | |
| 3430 | \\ .more() // | |
| 3431 | \\ .more().more() // | |
| 3432 | \\ .more() // | |
| 3433 | \\ // .more() // | |
| 3434 | \\ .more() // | |
| 3435 | \\ .more(); | |
| 3436 | \\ data: Data, | |
| 3437 | \\}; | |
| 3438 | \\ | |
| 3439 | \\pub const str = struct { | |
| 3440 | \\ pub const Thing = more.more // | |
| 3441 | \\ .more() // | |
| 3442 | \\ // .more() // | |
| 3443 | \\ // .more() // | |
| 3444 | \\ // .more() // | |
| 3445 | \\ .more() // | |
| 3446 | \\ .more(); | |
| 3447 | \\ data: Data, | |
| 3448 | \\}; | |
| 3449 | \\ | |
| 3450 | \\pub const str = struct { | |
| 3451 | \\ pub const Thing = more // | |
| 3452 | \\ .more // | |
| 3453 | \\ .more() // | |
| 3454 | \\ .more(); | |
| 3455 | \\ data: Data, | |
| 3456 | \\}; | |
| 3457 | \\ | |
| 3458 | ); | |
| 3459 | } | |
| 3460 | ||
| 3461 | test "zig fmt: Indent comma correctly after multiline string literals in arg list (trailing comma)" { | |
| 3462 | try testCanonical( | |
| 3463 | \\fn foo() void { | |
| 3464 | \\ z.display_message_dialog( | |
| 3465 | \\ *const [323:0]u8, | |
| 3466 | \\ \\Message Text | |
| 3467 | \\ \\------------ | |
| 3468 | \\ \\xxxxxxxxxxxx | |
| 3469 | \\ \\xxxxxxxxxxxx | |
| 3470 | \\ , | |
| 3471 | \\ g.GtkMessageType.GTK_MESSAGE_WARNING, | |
| 3472 | \\ null, | |
| 3473 | \\ ); | |
| 3474 | \\ | |
| 3475 | \\ z.display_message_dialog(*const [323:0]u8, | |
| 3476 | \\ \\Message Text | |
| 3477 | \\ \\------------ | |
| 3478 | \\ \\xxxxxxxxxxxx | |
| 3479 | \\ \\xxxxxxxxxxxx | |
| 3480 | \\ , g.GtkMessageType.GTK_MESSAGE_WARNING, null); | |
| 3481 | \\} | |
| 3482 | \\ | |
| 3483 | ); | |
| 3484 | } | |
| 3485 | ||
| 3486 | test "zig fmt: Control flow statement as body of blockless if" { | |
| 3487 | try testCanonical( | |
| 3488 | \\pub fn main() void { | |
| 3489 | \\ const zoom_node = if (focused_node == layout_first) | |
| 3490 | \\ if (it.next()) { | |
| 3491 | \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3492 | \\ } else null | |
| 3493 | \\ else | |
| 3494 | \\ focused_node; | |
| 3495 | \\ | |
| 3496 | \\ const zoom_node = if (focused_node == layout_first) while (it.next()) |node| { | |
| 3497 | \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3498 | \\ } else null else | |
| 3499 | \\ focused_node; | |
| 3500 | \\ | |
| 3501 | \\ const zoom_node = if (focused_node == layout_first) | |
| 3502 | \\ if (it.next()) { | |
| 3503 | \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3504 | \\ } else null; | |
| 3505 | \\ | |
| 3506 | \\ const zoom_node = if (focused_node == layout_first) while (it.next()) |node| { | |
| 3507 | \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3508 | \\ }; | |
| 3509 | \\ | |
| 3510 | \\ const zoom_node = if (focused_node == layout_first) for (nodes) |node| { | |
| 3511 | \\ break node; | |
| 3512 | \\ }; | |
| 3513 | \\ | |
| 3514 | \\ const zoom_node = if (focused_node == layout_first) switch (nodes) { | |
| 3515 | \\ 0 => 0, | |
| 3516 | \\ } else | |
| 3517 | \\ focused_node; | |
| 3518 | \\} | |
| 3519 | \\ | |
| 3520 | ); | |
| 3521 | } | |
| 3522 | ||
| 3523 | test "zig fmt: " { | |
| 3524 | try testCanonical( | |
| 3525 | \\pub fn sendViewTags(self: Self) void { | |
| 3526 | \\ var it = ViewStack(View).iterator(self.output.views.first, std.math.maxInt(u32)); | |
| 3527 | \\ while (it.next()) |node| | |
| 3528 | \\ view_tags.append(node.view.current_tags) catch { | |
| 3529 | \\ c.wl_resource_post_no_memory(self.wl_resource); | |
| 3530 | \\ log.crit(.river_status, "out of memory", .{}); | |
| 3531 | \\ return; | |
| 3532 | \\ }; | |
| 3533 | \\} | |
| 3534 | \\ | |
| 3535 | ); | |
| 3536 | } | |
| 3537 | ||
| 3538 | test "zig fmt: allow trailing line comments to do manual array formatting" { | |
| 3539 | try testCanonical( | |
| 3540 | \\fn foo() void { | |
| 3541 | \\ self.code.appendSliceAssumeCapacity(&[_]u8{ | |
| 3542 | \\ 0x55, // push rbp | |
| 3543 | \\ 0x48, 0x89, 0xe5, // mov rbp, rsp | |
| 3544 | \\ 0x48, 0x81, 0xec, // sub rsp, imm32 (with reloc) | |
| 3545 | \\ }); | |
| 3546 | \\ | |
| 3547 | \\ di_buf.appendAssumeCapacity(&[_]u8{ | |
| 3548 | \\ 1, DW.TAG_compile_unit, DW.CHILDREN_no, // header | |
| 3549 | \\ DW.AT_stmt_list, DW_FORM_data4, // form value pairs | |
| 3550 | \\ DW.AT_low_pc, DW_FORM_addr, | |
| 3551 | \\ DW.AT_high_pc, DW_FORM_addr, | |
| 3552 | \\ DW.AT_name, DW_FORM_strp, | |
| 3553 | \\ DW.AT_comp_dir, DW_FORM_strp, | |
| 3554 | \\ DW.AT_producer, DW_FORM_strp, | |
| 3555 | \\ DW.AT_language, DW_FORM_data2, | |
| 3556 | \\ 0, 0, // sentinel | |
| 3557 | \\ }); | |
| 3558 | \\ | |
| 3559 | \\ self.code.appendSliceAssumeCapacity(&[_]u8{ | |
| 3560 | \\ 0x55, // push rbp | |
| 3561 | \\ 0x48, 0x89, 0xe5, // mov rbp, rsp | |
| 3562 | \\ // How do we handle this? | |
| 3563 | \\ //0x48, 0x81, 0xec, // sub rsp, imm32 (with reloc) | |
| 3564 | \\ // Here's a blank line, should that be allowed? | |
| 3565 | \\ | |
| 3566 | \\ 0x48, 0x89, 0xe5, | |
| 3567 | \\ 0x33, 0x45, | |
| 3568 | \\ // Now the comment breaks a single line -- how do we handle this? | |
| 3569 | \\ 0x88, | |
| 3570 | \\ }); | |
| 3571 | \\} | |
| 3572 | \\ | |
| 3573 | ); | |
| 3574 | } | |
| 3575 | ||
| 3576 | test "zig fmt: multiline string literals should play nice with array initializers" { | |
| 3577 | try testCanonical( | |
| 3578 | \\fn main() void { | |
| 3579 | \\ var a = .{.{.{.{.{.{.{.{ | |
| 3580 | \\ 0, | |
| 3581 | \\ }}}}}}}}; | |
| 3582 | \\ myFunc(.{ | |
| 3583 | \\ "aaaaaaa", "bbbbbb", "ccccc", | |
| 3584 | \\ "dddd", ("eee"), ("fff"), | |
| 3585 | \\ ("gggg"), | |
| 3586 | \\ // Line comment | |
| 3587 | \\ \\Multiline String Literals can be quite long | |
| 3588 | \\ , | |
| 3589 | \\ \\Multiline String Literals can be quite long | |
| 3590 | \\ \\Multiline String Literals can be quite long | |
| 3591 | \\ , | |
| 3592 | \\ \\Multiline String Literals can be quite long | |
| 3593 | \\ \\Multiline String Literals can be quite long | |
| 3594 | \\ \\Multiline String Literals can be quite long | |
| 3595 | \\ \\Multiline String Literals can be quite long | |
| 3596 | \\ , | |
| 3597 | \\ ( | |
| 3598 | \\ \\Multiline String Literals can be quite long | |
| 3599 | \\ ), | |
| 3600 | \\ .{ | |
| 3601 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3602 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3603 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3604 | \\ }, | |
| 3605 | \\ .{( | |
| 3606 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3607 | \\ )}, | |
| 3608 | \\ .{ | |
| 3609 | \\ "xxxxxxx", "xxx", | |
| 3610 | \\ ( | |
| 3611 | \\ \\ xxx | |
| 3612 | \\ ), | |
| 3613 | \\ "xxx", "xxx", | |
| 3614 | \\ }, | |
| 3615 | \\ .{ "xxxxxxx", "xxx", "xxx", "xxx" }, .{ "xxxxxxx", "xxx", "xxx", "xxx" }, | |
| 3616 | \\ "aaaaaaa", "bbbbbb", "ccccc", // - | |
| 3617 | \\ "dddd", ("eee"), ("fff"), | |
| 3618 | \\ .{ | |
| 3619 | \\ "xxx", "xxx", | |
| 3620 | \\ ( | |
| 3621 | \\ \\ xxx | |
| 3622 | \\ ), | |
| 3623 | \\ "xxxxxxxxxxxxxx", "xxx", | |
| 3624 | \\ }, | |
| 3625 | \\ .{ | |
| 3626 | \\ ( | |
| 3627 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3628 | \\ ), | |
| 3629 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3630 | \\ }, | |
| 3631 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3632 | \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3633 | \\ }); | |
| 3634 | \\} | |
| 3635 | \\ | |
| 3636 | ); | |
| 3637 | } | |
| 3638 | ||
| 3639 | test "zig fmt: use of comments and Multiline string literals may force the parameters over multiple lines" { | |
| 3640 | try testCanonical( | |
| 3641 | \\pub fn makeMemUndefined(qzz: []u8) i1 { | |
| 3642 | \\ cases.add( // fixed bug #2032 | |
| 3643 | \\ "compile diagnostic string for top level decl type", | |
| 3644 | \\ \\export fn entry() void { | |
| 3645 | \\ \\ var foo: u32 = @This(){}; | |
| 3646 | \\ \\} | |
| 3647 | \\ , &[_][]const u8{ | |
| 3648 | \\ "tmp.zig:2:27: error: type 'u32' does not support array initialization", | |
| 3649 | \\ }); | |
| 3650 | \\ @compileError( | |
| 3651 | \\ \\ unknown-length pointers and C pointers cannot be hashed deeply. | |
| 3652 | \\ \\ Consider providing your own hash function. | |
| 3653 | \\ \\ unknown-length pointers and C pointers cannot be hashed deeply. | |
| 3654 | \\ \\ Consider providing your own hash function. | |
| 3655 | \\ ); | |
| 3656 | \\ return @intCast(i1, doMemCheckClientRequestExpr(0, // default return | |
| 3657 | \\ .MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0)); | |
| 3658 | \\} | |
| 3659 | \\ | |
| 3660 | \\// This looks like garbage don't do this | |
| 3661 | \\const rparen = tree.prevToken( | |
| 3662 | \\// the first token for the annotation expressions is the left | |
| 3663 | \\// parenthesis, hence the need for two prevToken | |
| 3664 | \\ if (fn_proto.getAlignExpr()) |align_expr| | |
| 3665 | \\ tree.prevToken(tree.prevToken(align_expr.firstToken())) | |
| 3666 | \\else if (fn_proto.getSectionExpr()) |section_expr| | |
| 3667 | \\ tree.prevToken(tree.prevToken(section_expr.firstToken())) | |
| 3668 | \\else if (fn_proto.getCallconvExpr()) |callconv_expr| | |
| 3669 | \\ tree.prevToken(tree.prevToken(callconv_expr.firstToken())) | |
| 3670 | \\else switch (fn_proto.return_type) { | |
| 3671 | \\ .Explicit => |node| node.firstToken(), | |
| 3672 | \\ .InferErrorSet => |node| tree.prevToken(node.firstToken()), | |
| 3673 | \\ .Invalid => unreachable, | |
| 3674 | \\}); | |
| 3675 | \\ | |
| 3676 | ); | |
| 3677 | } | |
| 3678 | ||
| 3679 | test "zig fmt: single argument trailing commas in @builtins()" { | |
| 3680 | try testCanonical( | |
| 3681 | \\pub fn foo(qzz: []u8) i1 { | |
| 3682 | \\ @panic( | |
| 3683 | \\ foo, | |
| 3684 | \\ ); | |
| 3685 | \\ panic( | |
| 3686 | \\ foo, | |
| 3687 | \\ ); | |
| 3688 | \\ @panic( | |
| 3689 | \\ foo, | |
| 3690 | \\ bar, | |
| 3691 | \\ ); | |
| 3692 | \\} | |
| 3693 | \\ | |
| 3694 | ); | |
| 3695 | } | |
| 3696 | ||
| 3697 | test "zig fmt: trailing comma should force multiline 1 column" { | |
| 3698 | try testTransform( | |
| 3699 | \\pub const UUID_NULL: uuid_t = [16]u8{0,0,0,0,}; | |
| 3700 | \\ | |
| 3701 | , | |
| 3702 | \\pub const UUID_NULL: uuid_t = [16]u8{ | |
| 3703 | \\ 0, | |
| 3704 | \\ 0, | |
| 3705 | \\ 0, | |
| 3706 | \\ 0, | |
| 3707 | \\}; | |
| 3708 | \\ | |
| 3709 | ); | |
| 3710 | } | |
| 3711 | ||
| 3712 | test "zig fmt: function params should align nicely" { | |
| 3713 | try testCanonical( | |
| 3714 | \\pub fn foo() void { | |
| 3715 | \\ cases.addRuntimeSafety("slicing operator with sentinel", | |
| 3716 | \\ \\const std = @import("std"); | |
| 3717 | \\ ++ check_panic_msg ++ | |
| 3718 | \\ \\pub fn main() void { | |
| 3719 | \\ \\ var buf = [4]u8{'a','b','c',0}; | |
| 3720 | \\ \\ const slice = buf[0..:0]; | |
| 3721 | \\ \\} | |
| 3722 | \\ ); | |
| 3723 | \\} | |
| 3724 | \\ | |
| 3725 | ); | |
| 3726 | } | |
| 6 | test "zig fmt: simple top level comptime block" { | |
| 7 | try testCanonical( | |
| 8 | \\comptime {} | |
| 9 | \\ | |
| 10 | ); | |
| 11 | } | |
| 12 | ||
| 13 | //test "recovery: top level" { | |
| 14 | // try testError( | |
| 15 | // \\test "" {inline} | |
| 16 | // \\test "" {inline} | |
| 17 | // , &[_]Error{ | |
| 18 | // .ExpectedInlinable, | |
| 19 | // .ExpectedInlinable, | |
| 20 | // }); | |
| 21 | //} | |
| 22 | // | |
| 23 | //test "recovery: block statements" { | |
| 24 | // try testError( | |
| 25 | // \\test "" { | |
| 26 | // \\ foo + +; | |
| 27 | // \\ inline; | |
| 28 | // \\} | |
| 29 | // , &[_]Error{ | |
| 30 | // .InvalidToken, | |
| 31 | // .ExpectedInlinable, | |
| 32 | // }); | |
| 33 | //} | |
| 34 | // | |
| 35 | //test "recovery: missing comma" { | |
| 36 | // try testError( | |
| 37 | // \\test "" { | |
| 38 | // \\ switch (foo) { | |
| 39 | // \\ 2 => {} | |
| 40 | // \\ 3 => {} | |
| 41 | // \\ else => { | |
| 42 | // \\ foo && bar +; | |
| 43 | // \\ } | |
| 44 | // \\ } | |
| 45 | // \\} | |
| 46 | // , &[_]Error{ | |
| 47 | // .ExpectedToken, | |
| 48 | // .ExpectedToken, | |
| 49 | // .InvalidAnd, | |
| 50 | // .InvalidToken, | |
| 51 | // }); | |
| 52 | //} | |
| 53 | // | |
| 54 | //test "recovery: extra qualifier" { | |
| 55 | // try testError( | |
| 56 | // \\const a: *const const u8; | |
| 57 | // \\test "" | |
| 58 | // , &[_]Error{ | |
| 59 | // .ExtraConstQualifier, | |
| 60 | // .ExpectedLBrace, | |
| 61 | // }); | |
| 62 | //} | |
| 63 | // | |
| 64 | //test "recovery: missing return type" { | |
| 65 | // try testError( | |
| 66 | // \\fn foo() { | |
| 67 | // \\ a && b; | |
| 68 | // \\} | |
| 69 | // \\test "" | |
| 70 | // , &[_]Error{ | |
| 71 | // .ExpectedReturnType, | |
| 72 | // .InvalidAnd, | |
| 73 | // .ExpectedLBrace, | |
| 74 | // }); | |
| 75 | //} | |
| 76 | // | |
| 77 | //test "recovery: continue after invalid decl" { | |
| 78 | // try testError( | |
| 79 | // \\fn foo { | |
| 80 | // \\ inline; | |
| 81 | // \\} | |
| 82 | // \\pub test "" { | |
| 83 | // \\ async a && b; | |
| 84 | // \\} | |
| 85 | // , &[_]Error{ | |
| 86 | // .ExpectedToken, | |
| 87 | // .ExpectedPubItem, | |
| 88 | // .ExpectedParamList, | |
| 89 | // .InvalidAnd, | |
| 90 | // }); | |
| 91 | // try testError( | |
| 92 | // \\threadlocal test "" { | |
| 93 | // \\ @a && b; | |
| 94 | // \\} | |
| 95 | // , &[_]Error{ | |
| 96 | // .ExpectedVarDecl, | |
| 97 | // .ExpectedParamList, | |
| 98 | // .InvalidAnd, | |
| 99 | // }); | |
| 100 | //} | |
| 101 | // | |
| 102 | //test "recovery: invalid extern/inline" { | |
| 103 | // try testError( | |
| 104 | // \\inline test "" { a && b; } | |
| 105 | // , &[_]Error{ | |
| 106 | // .ExpectedFn, | |
| 107 | // .InvalidAnd, | |
| 108 | // }); | |
| 109 | // try testError( | |
| 110 | // \\extern "" test "" { a && b; } | |
| 111 | // , &[_]Error{ | |
| 112 | // .ExpectedVarDeclOrFn, | |
| 113 | // .InvalidAnd, | |
| 114 | // }); | |
| 115 | //} | |
| 116 | // | |
| 117 | //test "recovery: missing semicolon" { | |
| 118 | // try testError( | |
| 119 | // \\test "" { | |
| 120 | // \\ comptime a && b | |
| 121 | // \\ c && d | |
| 122 | // \\ @foo | |
| 123 | // \\} | |
| 124 | // , &[_]Error{ | |
| 125 | // .InvalidAnd, | |
| 126 | // .ExpectedToken, | |
| 127 | // .InvalidAnd, | |
| 128 | // .ExpectedToken, | |
| 129 | // .ExpectedParamList, | |
| 130 | // .ExpectedToken, | |
| 131 | // }); | |
| 132 | //} | |
| 133 | // | |
| 134 | //test "recovery: invalid container members" { | |
| 135 | // try testError( | |
| 136 | // \\usingnamespace; | |
| 137 | // \\foo+ | |
| 138 | // \\bar@, | |
| 139 | // \\while (a == 2) { test "" {}} | |
| 140 | // \\test "" { | |
| 141 | // \\ a && b | |
| 142 | // \\} | |
| 143 | // , &[_]Error{ | |
| 144 | // .ExpectedExpr, | |
| 145 | // .ExpectedToken, | |
| 146 | // .ExpectedToken, | |
| 147 | // .ExpectedContainerMembers, | |
| 148 | // .InvalidAnd, | |
| 149 | // .ExpectedToken, | |
| 150 | // }); | |
| 151 | //} | |
| 152 | // | |
| 153 | //test "recovery: invalid parameter" { | |
| 154 | // try testError( | |
| 155 | // \\fn main() void { | |
| 156 | // \\ a(comptime T: type) | |
| 157 | // \\} | |
| 158 | // , &[_]Error{ | |
| 159 | // .ExpectedToken, | |
| 160 | // }); | |
| 161 | //} | |
| 162 | // | |
| 163 | //test "recovery: extra '}' at top level" { | |
| 164 | // try testError( | |
| 165 | // \\}}} | |
| 166 | // \\test "" { | |
| 167 | // \\ a && b; | |
| 168 | // \\} | |
| 169 | // , &[_]Error{ | |
| 170 | // .ExpectedContainerMembers, | |
| 171 | // .ExpectedContainerMembers, | |
| 172 | // .ExpectedContainerMembers, | |
| 173 | // .InvalidAnd, | |
| 174 | // }); | |
| 175 | //} | |
| 176 | // | |
| 177 | //test "recovery: mismatched bracket at top level" { | |
| 178 | // try testError( | |
| 179 | // \\const S = struct { | |
| 180 | // \\ arr: 128]?G | |
| 181 | // \\}; | |
| 182 | // , &[_]Error{ | |
| 183 | // .ExpectedToken, | |
| 184 | // }); | |
| 185 | //} | |
| 186 | // | |
| 187 | //test "recovery: invalid global error set access" { | |
| 188 | // try testError( | |
| 189 | // \\test "" { | |
| 190 | // \\ error && foo; | |
| 191 | // \\} | |
| 192 | // , &[_]Error{ | |
| 193 | // .ExpectedToken, | |
| 194 | // .ExpectedIdentifier, | |
| 195 | // .InvalidAnd, | |
| 196 | // }); | |
| 197 | //} | |
| 198 | // | |
| 199 | //test "recovery: invalid asterisk after pointer dereference" { | |
| 200 | // try testError( | |
| 201 | // \\test "" { | |
| 202 | // \\ var sequence = "repeat".*** 10; | |
| 203 | // \\} | |
| 204 | // , &[_]Error{ | |
| 205 | // .AsteriskAfterPointerDereference, | |
| 206 | // }); | |
| 207 | // try testError( | |
| 208 | // \\test "" { | |
| 209 | // \\ var sequence = "repeat".** 10&&a; | |
| 210 | // \\} | |
| 211 | // , &[_]Error{ | |
| 212 | // .AsteriskAfterPointerDereference, | |
| 213 | // .InvalidAnd, | |
| 214 | // }); | |
| 215 | //} | |
| 216 | // | |
| 217 | //test "recovery: missing semicolon after if, for, while stmt" { | |
| 218 | // try testError( | |
| 219 | // \\test "" { | |
| 220 | // \\ if (foo) bar | |
| 221 | // \\ for (foo) |a| bar | |
| 222 | // \\ while (foo) bar | |
| 223 | // \\ a && b; | |
| 224 | // \\} | |
| 225 | // , &[_]Error{ | |
| 226 | // .ExpectedSemiOrElse, | |
| 227 | // .ExpectedSemiOrElse, | |
| 228 | // .ExpectedSemiOrElse, | |
| 229 | // .InvalidAnd, | |
| 230 | // }); | |
| 231 | //} | |
| 232 | // | |
| 233 | //test "recovery: invalid comptime" { | |
| 234 | // try testError( | |
| 235 | // \\comptime | |
| 236 | // , &[_]Error{ | |
| 237 | // .ExpectedBlockOrField, | |
| 238 | // }); | |
| 239 | //} | |
| 240 | // | |
| 241 | //test "recovery: missing block after for/while loops" { | |
| 242 | // try testError( | |
| 243 | // \\test "" { while (foo) } | |
| 244 | // , &[_]Error{ | |
| 245 | // .ExpectedBlockOrAssignment, | |
| 246 | // }); | |
| 247 | // try testError( | |
| 248 | // \\test "" { for (foo) |bar| } | |
| 249 | // , &[_]Error{ | |
| 250 | // .ExpectedBlockOrAssignment, | |
| 251 | // }); | |
| 252 | //} | |
| 253 | // | |
| 254 | //test "zig fmt: respect line breaks after var declarations" { | |
| 255 | // try testCanonical( | |
| 256 | // \\const crc = | |
| 257 | // \\ lookup_tables[0][p[7]] ^ | |
| 258 | // \\ lookup_tables[1][p[6]] ^ | |
| 259 | // \\ lookup_tables[2][p[5]] ^ | |
| 260 | // \\ lookup_tables[3][p[4]] ^ | |
| 261 | // \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^ | |
| 262 | // \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^ | |
| 263 | // \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^ | |
| 264 | // \\ lookup_tables[7][@truncate(u8, self.crc >> 0)]; | |
| 265 | // \\ | |
| 266 | // ); | |
| 267 | //} | |
| 268 | // | |
| 269 | //test "zig fmt: multiline string mixed with comments" { | |
| 270 | // try testCanonical( | |
| 271 | // \\const s1 = | |
| 272 | // \\ //\\one | |
| 273 | // \\ \\two) | |
| 274 | // \\ \\three | |
| 275 | // \\; | |
| 276 | // \\const s2 = | |
| 277 | // \\ \\one | |
| 278 | // \\ \\two) | |
| 279 | // \\ //\\three | |
| 280 | // \\; | |
| 281 | // \\const s3 = | |
| 282 | // \\ \\one | |
| 283 | // \\ //\\two) | |
| 284 | // \\ \\three | |
| 285 | // \\; | |
| 286 | // \\const s4 = | |
| 287 | // \\ \\one | |
| 288 | // \\ //\\two | |
| 289 | // \\ \\three | |
| 290 | // \\ //\\four | |
| 291 | // \\ \\five | |
| 292 | // \\; | |
| 293 | // \\const a = | |
| 294 | // \\ 1; | |
| 295 | // \\ | |
| 296 | // ); | |
| 297 | //} | |
| 298 | // | |
| 299 | //test "zig fmt: empty file" { | |
| 300 | // try testCanonical( | |
| 301 | // \\ | |
| 302 | // ); | |
| 303 | //} | |
| 304 | // | |
| 305 | //test "zig fmt: if statment" { | |
| 306 | // try testCanonical( | |
| 307 | // \\test "" { | |
| 308 | // \\ if (optional()) |some| | |
| 309 | // \\ bar = some.foo(); | |
| 310 | // \\} | |
| 311 | // \\ | |
| 312 | // ); | |
| 313 | //} | |
| 314 | // | |
| 315 | //test "zig fmt: top-level fields" { | |
| 316 | // try testCanonical( | |
| 317 | // \\a: did_you_know, | |
| 318 | // \\b: all_files_are, | |
| 319 | // \\structs: ?x, | |
| 320 | // \\ | |
| 321 | // ); | |
| 322 | //} | |
| 323 | // | |
| 324 | //test "zig fmt: decl between fields" { | |
| 325 | // try testError( | |
| 326 | // \\const S = struct { | |
| 327 | // \\ const foo = 2; | |
| 328 | // \\ const bar = 2; | |
| 329 | // \\ const baz = 2; | |
| 330 | // \\ a: usize, | |
| 331 | // \\ const foo1 = 2; | |
| 332 | // \\ const bar1 = 2; | |
| 333 | // \\ const baz1 = 2; | |
| 334 | // \\ b: usize, | |
| 335 | // \\}; | |
| 336 | // , &[_]Error{ | |
| 337 | // .DeclBetweenFields, | |
| 338 | // }); | |
| 339 | //} | |
| 340 | // | |
| 341 | //test "zig fmt: eof after missing comma" { | |
| 342 | // try testError( | |
| 343 | // \\foo() | |
| 344 | // , &[_]Error{ | |
| 345 | // .ExpectedToken, | |
| 346 | // }); | |
| 347 | //} | |
| 348 | // | |
| 349 | //test "zig fmt: errdefer with payload" { | |
| 350 | // try testCanonical( | |
| 351 | // \\pub fn main() anyerror!void { | |
| 352 | // \\ errdefer |a| x += 1; | |
| 353 | // \\ errdefer |a| {} | |
| 354 | // \\ errdefer |a| { | |
| 355 | // \\ x += 1; | |
| 356 | // \\ } | |
| 357 | // \\} | |
| 358 | // \\ | |
| 359 | // ); | |
| 360 | //} | |
| 361 | // | |
| 362 | //test "zig fmt: nosuspend block" { | |
| 363 | // try testCanonical( | |
| 364 | // \\pub fn main() anyerror!void { | |
| 365 | // \\ nosuspend { | |
| 366 | // \\ var foo: Foo = .{ .bar = 42 }; | |
| 367 | // \\ } | |
| 368 | // \\} | |
| 369 | // \\ | |
| 370 | // ); | |
| 371 | //} | |
| 372 | // | |
| 373 | //test "zig fmt: nosuspend await" { | |
| 374 | // try testCanonical( | |
| 375 | // \\fn foo() void { | |
| 376 | // \\ x = nosuspend await y; | |
| 377 | // \\} | |
| 378 | // \\ | |
| 379 | // ); | |
| 380 | //} | |
| 381 | // | |
| 382 | //test "zig fmt: trailing comma in container declaration" { | |
| 383 | // try testCanonical( | |
| 384 | // \\const X = struct { foo: i32 }; | |
| 385 | // \\const X = struct { foo: i32, bar: i32 }; | |
| 386 | // \\const X = struct { foo: i32 = 1, bar: i32 = 2 }; | |
| 387 | // \\const X = struct { foo: i32 align(4), bar: i32 align(4) }; | |
| 388 | // \\const X = struct { foo: i32 align(4) = 1, bar: i32 align(4) = 2 }; | |
| 389 | // \\ | |
| 390 | // ); | |
| 391 | // try testCanonical( | |
| 392 | // \\test "" { | |
| 393 | // \\ comptime { | |
| 394 | // \\ const X = struct { | |
| 395 | // \\ x: i32 | |
| 396 | // \\ }; | |
| 397 | // \\ } | |
| 398 | // \\} | |
| 399 | // \\ | |
| 400 | // ); | |
| 401 | // try testTransform( | |
| 402 | // \\const X = struct { | |
| 403 | // \\ foo: i32, bar: i8 }; | |
| 404 | // , | |
| 405 | // \\const X = struct { | |
| 406 | // \\ foo: i32, bar: i8 | |
| 407 | // \\}; | |
| 408 | // \\ | |
| 409 | // ); | |
| 410 | //} | |
| 411 | // | |
| 412 | //test "zig fmt: trailing comma in fn parameter list" { | |
| 413 | // try testCanonical( | |
| 414 | // \\pub fn f( | |
| 415 | // \\ a: i32, | |
| 416 | // \\ b: i32, | |
| 417 | // \\) i32 {} | |
| 418 | // \\pub fn f( | |
| 419 | // \\ a: i32, | |
| 420 | // \\ b: i32, | |
| 421 | // \\) align(8) i32 {} | |
| 422 | // \\pub fn f( | |
| 423 | // \\ a: i32, | |
| 424 | // \\ b: i32, | |
| 425 | // \\) linksection(".text") i32 {} | |
| 426 | // \\pub fn f( | |
| 427 | // \\ a: i32, | |
| 428 | // \\ b: i32, | |
| 429 | // \\) callconv(.C) i32 {} | |
| 430 | // \\pub fn f( | |
| 431 | // \\ a: i32, | |
| 432 | // \\ b: i32, | |
| 433 | // \\) align(8) linksection(".text") i32 {} | |
| 434 | // \\pub fn f( | |
| 435 | // \\ a: i32, | |
| 436 | // \\ b: i32, | |
| 437 | // \\) align(8) callconv(.C) i32 {} | |
| 438 | // \\pub fn f( | |
| 439 | // \\ a: i32, | |
| 440 | // \\ b: i32, | |
| 441 | // \\) align(8) linksection(".text") callconv(.C) i32 {} | |
| 442 | // \\pub fn f( | |
| 443 | // \\ a: i32, | |
| 444 | // \\ b: i32, | |
| 445 | // \\) linksection(".text") callconv(.C) i32 {} | |
| 446 | // \\ | |
| 447 | // ); | |
| 448 | //} | |
| 449 | // | |
| 450 | //test "zig fmt: comptime struct field" { | |
| 451 | // try testCanonical( | |
| 452 | // \\const Foo = struct { | |
| 453 | // \\ a: i32, | |
| 454 | // \\ comptime b: i32 = 1234, | |
| 455 | // \\}; | |
| 456 | // \\ | |
| 457 | // ); | |
| 458 | //} | |
| 459 | // | |
| 460 | //test "zig fmt: c pointer type" { | |
| 461 | // try testCanonical( | |
| 462 | // \\pub extern fn repro() [*c]const u8; | |
| 463 | // \\ | |
| 464 | // ); | |
| 465 | //} | |
| 466 | // | |
| 467 | //test "zig fmt: builtin call with trailing comma" { | |
| 468 | // try testCanonical( | |
| 469 | // \\pub fn main() void { | |
| 470 | // \\ @breakpoint(); | |
| 471 | // \\ _ = @boolToInt(a); | |
| 472 | // \\ _ = @call( | |
| 473 | // \\ a, | |
| 474 | // \\ b, | |
| 475 | // \\ c, | |
| 476 | // \\ ); | |
| 477 | // \\} | |
| 478 | // \\ | |
| 479 | // ); | |
| 480 | //} | |
| 481 | // | |
| 482 | //test "zig fmt: asm expression with comptime content" { | |
| 483 | // try testCanonical( | |
| 484 | // \\comptime { | |
| 485 | // \\ asm ("foo" ++ "bar"); | |
| 486 | // \\} | |
| 487 | // \\pub fn main() void { | |
| 488 | // \\ asm volatile ("foo" ++ "bar"); | |
| 489 | // \\ asm volatile ("foo" ++ "bar" | |
| 490 | // \\ : [_] "" (x) | |
| 491 | // \\ ); | |
| 492 | // \\ asm volatile ("foo" ++ "bar" | |
| 493 | // \\ : [_] "" (x) | |
| 494 | // \\ : [_] "" (y) | |
| 495 | // \\ ); | |
| 496 | // \\ asm volatile ("foo" ++ "bar" | |
| 497 | // \\ : [_] "" (x) | |
| 498 | // \\ : [_] "" (y) | |
| 499 | // \\ : "h", "e", "l", "l", "o" | |
| 500 | // \\ ); | |
| 501 | // \\} | |
| 502 | // \\ | |
| 503 | // ); | |
| 504 | //} | |
| 505 | // | |
| 506 | //test "zig fmt: anytype struct field" { | |
| 507 | // try testCanonical( | |
| 508 | // \\pub const Pointer = struct { | |
| 509 | // \\ sentinel: anytype, | |
| 510 | // \\}; | |
| 511 | // \\ | |
| 512 | // ); | |
| 513 | //} | |
| 514 | // | |
| 515 | //test "zig fmt: sentinel-terminated array type" { | |
| 516 | // try testCanonical( | |
| 517 | // \\pub fn cStrToPrefixedFileW(s: [*:0]const u8) ![PATH_MAX_WIDE:0]u16 { | |
| 518 | // \\ return sliceToPrefixedFileW(mem.toSliceConst(u8, s)); | |
| 519 | // \\} | |
| 520 | // \\ | |
| 521 | // ); | |
| 522 | //} | |
| 523 | // | |
| 524 | //test "zig fmt: sentinel-terminated slice type" { | |
| 525 | // try testCanonical( | |
| 526 | // \\pub fn toSlice(self: Buffer) [:0]u8 { | |
| 527 | // \\ return self.list.toSlice()[0..self.len()]; | |
| 528 | // \\} | |
| 529 | // \\ | |
| 530 | // ); | |
| 531 | //} | |
| 532 | // | |
| 533 | //test "zig fmt: anon literal in array" { | |
| 534 | // try testCanonical( | |
| 535 | // \\var arr: [2]Foo = .{ | |
| 536 | // \\ .{ .a = 2 }, | |
| 537 | // \\ .{ .b = 3 }, | |
| 538 | // \\}; | |
| 539 | // \\ | |
| 540 | // ); | |
| 541 | //} | |
| 542 | // | |
| 543 | //test "zig fmt: alignment in anonymous literal" { | |
| 544 | // try testTransform( | |
| 545 | // \\const a = .{ | |
| 546 | // \\ "U", "L", "F", | |
| 547 | // \\ "U'", | |
| 548 | // \\ "L'", | |
| 549 | // \\ "F'", | |
| 550 | // \\}; | |
| 551 | // \\ | |
| 552 | // , | |
| 553 | // \\const a = .{ | |
| 554 | // \\ "U", "L", "F", | |
| 555 | // \\ "U'", "L'", "F'", | |
| 556 | // \\}; | |
| 557 | // \\ | |
| 558 | // ); | |
| 559 | //} | |
| 560 | // | |
| 561 | //test "zig fmt: anon struct literal syntax" { | |
| 562 | // try testCanonical( | |
| 563 | // \\const x = .{ | |
| 564 | // \\ .a = b, | |
| 565 | // \\ .c = d, | |
| 566 | // \\}; | |
| 567 | // \\ | |
| 568 | // ); | |
| 569 | //} | |
| 570 | // | |
| 571 | //test "zig fmt: anon list literal syntax" { | |
| 572 | // try testCanonical( | |
| 573 | // \\const x = .{ a, b, c }; | |
| 574 | // \\ | |
| 575 | // ); | |
| 576 | //} | |
| 577 | // | |
| 578 | //test "zig fmt: async function" { | |
| 579 | // try testCanonical( | |
| 580 | // \\pub const Server = struct { | |
| 581 | // \\ handleRequestFn: fn (*Server, *const std.net.Address, File) callconv(.Async) void, | |
| 582 | // \\}; | |
| 583 | // \\test "hi" { | |
| 584 | // \\ var ptr = @ptrCast(fn (i32) callconv(.Async) void, other); | |
| 585 | // \\} | |
| 586 | // \\ | |
| 587 | // ); | |
| 588 | //} | |
| 589 | // | |
| 590 | //test "zig fmt: whitespace fixes" { | |
| 591 | // try testTransform("test \"\" {\r\n\tconst hi = x;\r\n}\n// zig fmt: off\ntest \"\"{\r\n\tconst a = b;}\r\n", | |
| 592 | // \\test "" { | |
| 593 | // \\ const hi = x; | |
| 594 | // \\} | |
| 595 | // \\// zig fmt: off | |
| 596 | // \\test ""{ | |
| 597 | // \\ const a = b;} | |
| 598 | // \\ | |
| 599 | // ); | |
| 600 | //} | |
| 601 | // | |
| 602 | //test "zig fmt: while else err prong with no block" { | |
| 603 | // try testCanonical( | |
| 604 | // \\test "" { | |
| 605 | // \\ const result = while (returnError()) |value| { | |
| 606 | // \\ break value; | |
| 607 | // \\ } else |err| @as(i32, 2); | |
| 608 | // \\ expect(result == 2); | |
| 609 | // \\} | |
| 610 | // \\ | |
| 611 | // ); | |
| 612 | //} | |
| 613 | // | |
| 614 | //test "zig fmt: tagged union with enum values" { | |
| 615 | // try testCanonical( | |
| 616 | // \\const MultipleChoice2 = union(enum(u32)) { | |
| 617 | // \\ Unspecified1: i32, | |
| 618 | // \\ A: f32 = 20, | |
| 619 | // \\ Unspecified2: void, | |
| 620 | // \\ B: bool = 40, | |
| 621 | // \\ Unspecified3: i32, | |
| 622 | // \\ C: i8 = 60, | |
| 623 | // \\ Unspecified4: void, | |
| 624 | // \\ D: void = 1000, | |
| 625 | // \\ Unspecified5: i32, | |
| 626 | // \\}; | |
| 627 | // \\ | |
| 628 | // ); | |
| 629 | //} | |
| 630 | // | |
| 631 | //test "zig fmt: allowzero pointer" { | |
| 632 | // try testCanonical( | |
| 633 | // \\const T = [*]allowzero const u8; | |
| 634 | // \\ | |
| 635 | // ); | |
| 636 | //} | |
| 637 | // | |
| 638 | //test "zig fmt: enum literal" { | |
| 639 | // try testCanonical( | |
| 640 | // \\const x = .hi; | |
| 641 | // \\ | |
| 642 | // ); | |
| 643 | //} | |
| 644 | // | |
| 645 | //test "zig fmt: enum literal inside array literal" { | |
| 646 | // try testCanonical( | |
| 647 | // \\test "enums in arrays" { | |
| 648 | // \\ var colors = []Color{.Green}; | |
| 649 | // \\ colors = []Colors{ .Green, .Cyan }; | |
| 650 | // \\ colors = []Colors{ | |
| 651 | // \\ .Grey, | |
| 652 | // \\ .Green, | |
| 653 | // \\ .Cyan, | |
| 654 | // \\ }; | |
| 655 | // \\} | |
| 656 | // \\ | |
| 657 | // ); | |
| 658 | //} | |
| 659 | // | |
| 660 | //test "zig fmt: character literal larger than u8" { | |
| 661 | // try testCanonical( | |
| 662 | // \\const x = '\u{01f4a9}'; | |
| 663 | // \\ | |
| 664 | // ); | |
| 665 | //} | |
| 666 | // | |
| 667 | //test "zig fmt: infix operator and then multiline string literal" { | |
| 668 | // try testCanonical( | |
| 669 | // \\const x = "" ++ | |
| 670 | // \\ \\ hi | |
| 671 | // \\; | |
| 672 | // \\ | |
| 673 | // ); | |
| 674 | //} | |
| 675 | // | |
| 676 | //test "zig fmt: infix operator and then multiline string literal" { | |
| 677 | // try testCanonical( | |
| 678 | // \\const x = "" ++ | |
| 679 | // \\ \\ hi0 | |
| 680 | // \\ \\ hi1 | |
| 681 | // \\ \\ hi2 | |
| 682 | // \\; | |
| 683 | // \\ | |
| 684 | // ); | |
| 685 | //} | |
| 686 | // | |
| 687 | //test "zig fmt: C pointers" { | |
| 688 | // try testCanonical( | |
| 689 | // \\const Ptr = [*c]i32; | |
| 690 | // \\ | |
| 691 | // ); | |
| 692 | //} | |
| 693 | // | |
| 694 | //test "zig fmt: threadlocal" { | |
| 695 | // try testCanonical( | |
| 696 | // \\threadlocal var x: i32 = 1234; | |
| 697 | // \\ | |
| 698 | // ); | |
| 699 | //} | |
| 700 | // | |
| 701 | //test "zig fmt: linksection" { | |
| 702 | // try testCanonical( | |
| 703 | // \\export var aoeu: u64 linksection(".text.derp") = 1234; | |
| 704 | // \\export fn _start() linksection(".text.boot") callconv(.Naked) noreturn {} | |
| 705 | // \\ | |
| 706 | // ); | |
| 707 | //} | |
| 708 | // | |
| 709 | //test "zig fmt: correctly move doc comments on struct fields" { | |
| 710 | // try testTransform( | |
| 711 | // \\pub const section_64 = extern struct { | |
| 712 | // \\ sectname: [16]u8, /// name of this section | |
| 713 | // \\ segname: [16]u8, /// segment this section goes in | |
| 714 | // \\}; | |
| 715 | // , | |
| 716 | // \\pub const section_64 = extern struct { | |
| 717 | // \\ /// name of this section | |
| 718 | // \\ sectname: [16]u8, | |
| 719 | // \\ /// segment this section goes in | |
| 720 | // \\ segname: [16]u8, | |
| 721 | // \\}; | |
| 722 | // \\ | |
| 723 | // ); | |
| 724 | //} | |
| 725 | // | |
| 726 | //test "zig fmt: correctly space struct fields with doc comments" { | |
| 727 | // try testTransform( | |
| 728 | // \\pub const S = struct { | |
| 729 | // \\ /// A | |
| 730 | // \\ a: u8, | |
| 731 | // \\ /// B | |
| 732 | // \\ /// B (cont) | |
| 733 | // \\ b: u8, | |
| 734 | // \\ | |
| 735 | // \\ | |
| 736 | // \\ /// C | |
| 737 | // \\ c: u8, | |
| 738 | // \\}; | |
| 739 | // \\ | |
| 740 | // , | |
| 741 | // \\pub const S = struct { | |
| 742 | // \\ /// A | |
| 743 | // \\ a: u8, | |
| 744 | // \\ /// B | |
| 745 | // \\ /// B (cont) | |
| 746 | // \\ b: u8, | |
| 747 | // \\ | |
| 748 | // \\ /// C | |
| 749 | // \\ c: u8, | |
| 750 | // \\}; | |
| 751 | // \\ | |
| 752 | // ); | |
| 753 | //} | |
| 754 | // | |
| 755 | //test "zig fmt: doc comments on param decl" { | |
| 756 | // try testCanonical( | |
| 757 | // \\pub const Allocator = struct { | |
| 758 | // \\ shrinkFn: fn ( | |
| 759 | // \\ self: *Allocator, | |
| 760 | // \\ /// Guaranteed to be the same as what was returned from most recent call to | |
| 761 | // \\ /// `allocFn`, `reallocFn`, or `shrinkFn`. | |
| 762 | // \\ old_mem: []u8, | |
| 763 | // \\ /// Guaranteed to be the same as what was returned from most recent call to | |
| 764 | // \\ /// `allocFn`, `reallocFn`, or `shrinkFn`. | |
| 765 | // \\ old_alignment: u29, | |
| 766 | // \\ /// Guaranteed to be less than or equal to `old_mem.len`. | |
| 767 | // \\ new_byte_count: usize, | |
| 768 | // \\ /// Guaranteed to be less than or equal to `old_alignment`. | |
| 769 | // \\ new_alignment: u29, | |
| 770 | // \\ ) []u8, | |
| 771 | // \\}; | |
| 772 | // \\ | |
| 773 | // ); | |
| 774 | //} | |
| 775 | // | |
| 776 | //test "zig fmt: aligned struct field" { | |
| 777 | // try testCanonical( | |
| 778 | // \\pub const S = struct { | |
| 779 | // \\ f: i32 align(32), | |
| 780 | // \\}; | |
| 781 | // \\ | |
| 782 | // ); | |
| 783 | // try testCanonical( | |
| 784 | // \\pub const S = struct { | |
| 785 | // \\ f: i32 align(32) = 1, | |
| 786 | // \\}; | |
| 787 | // \\ | |
| 788 | // ); | |
| 789 | //} | |
| 790 | // | |
| 791 | //test "zig fmt: comment to disable/enable zig fmt first" { | |
| 792 | // try testCanonical( | |
| 793 | // \\// Test trailing comma syntax | |
| 794 | // \\// zig fmt: off | |
| 795 | // \\ | |
| 796 | // \\const struct_trailing_comma = struct { x: i32, y: i32, }; | |
| 797 | // ); | |
| 798 | //} | |
| 799 | // | |
| 800 | //test "zig fmt: comment to disable/enable zig fmt" { | |
| 801 | // try testTransform( | |
| 802 | // \\const a = b; | |
| 803 | // \\// zig fmt: off | |
| 804 | // \\const c = d; | |
| 805 | // \\// zig fmt: on | |
| 806 | // \\const e = f; | |
| 807 | // , | |
| 808 | // \\const a = b; | |
| 809 | // \\// zig fmt: off | |
| 810 | // \\const c = d; | |
| 811 | // \\// zig fmt: on | |
| 812 | // \\const e = f; | |
| 813 | // \\ | |
| 814 | // ); | |
| 815 | //} | |
| 816 | // | |
| 817 | //test "zig fmt: line comment following 'zig fmt: off'" { | |
| 818 | // try testCanonical( | |
| 819 | // \\// zig fmt: off | |
| 820 | // \\// Test | |
| 821 | // \\const e = f; | |
| 822 | // ); | |
| 823 | //} | |
| 824 | // | |
| 825 | //test "zig fmt: doc comment following 'zig fmt: off'" { | |
| 826 | // try testCanonical( | |
| 827 | // \\// zig fmt: off | |
| 828 | // \\/// test | |
| 829 | // \\const e = f; | |
| 830 | // ); | |
| 831 | //} | |
| 832 | // | |
| 833 | //test "zig fmt: line and doc comment following 'zig fmt: off'" { | |
| 834 | // try testCanonical( | |
| 835 | // \\// zig fmt: off | |
| 836 | // \\// test 1 | |
| 837 | // \\/// test 2 | |
| 838 | // \\const e = f; | |
| 839 | // ); | |
| 840 | //} | |
| 841 | // | |
| 842 | //test "zig fmt: doc and line comment following 'zig fmt: off'" { | |
| 843 | // try testCanonical( | |
| 844 | // \\// zig fmt: off | |
| 845 | // \\/// test 1 | |
| 846 | // \\// test 2 | |
| 847 | // \\const e = f; | |
| 848 | // ); | |
| 849 | //} | |
| 850 | // | |
| 851 | //test "zig fmt: alternating 'zig fmt: off' and 'zig fmt: on'" { | |
| 852 | // try testCanonical( | |
| 853 | // \\// zig fmt: off | |
| 854 | // \\// zig fmt: on | |
| 855 | // \\// zig fmt: off | |
| 856 | // \\const e = f; | |
| 857 | // \\// zig fmt: off | |
| 858 | // \\// zig fmt: on | |
| 859 | // \\// zig fmt: off | |
| 860 | // \\const a = b; | |
| 861 | // \\// zig fmt: on | |
| 862 | // \\const c = d; | |
| 863 | // \\// zig fmt: on | |
| 864 | // \\ | |
| 865 | // ); | |
| 866 | //} | |
| 867 | // | |
| 868 | //test "zig fmt: line comment following 'zig fmt: on'" { | |
| 869 | // try testCanonical( | |
| 870 | // \\// zig fmt: off | |
| 871 | // \\const e = f; | |
| 872 | // \\// zig fmt: on | |
| 873 | // \\// test | |
| 874 | // \\const e = f; | |
| 875 | // \\ | |
| 876 | // ); | |
| 877 | //} | |
| 878 | // | |
| 879 | //test "zig fmt: doc comment following 'zig fmt: on'" { | |
| 880 | // try testCanonical( | |
| 881 | // \\// zig fmt: off | |
| 882 | // \\const e = f; | |
| 883 | // \\// zig fmt: on | |
| 884 | // \\/// test | |
| 885 | // \\const e = f; | |
| 886 | // \\ | |
| 887 | // ); | |
| 888 | //} | |
| 889 | // | |
| 890 | //test "zig fmt: line and doc comment following 'zig fmt: on'" { | |
| 891 | // try testCanonical( | |
| 892 | // \\// zig fmt: off | |
| 893 | // \\const e = f; | |
| 894 | // \\// zig fmt: on | |
| 895 | // \\// test1 | |
| 896 | // \\/// test2 | |
| 897 | // \\const e = f; | |
| 898 | // \\ | |
| 899 | // ); | |
| 900 | //} | |
| 901 | // | |
| 902 | //test "zig fmt: doc and line comment following 'zig fmt: on'" { | |
| 903 | // try testCanonical( | |
| 904 | // \\// zig fmt: off | |
| 905 | // \\const e = f; | |
| 906 | // \\// zig fmt: on | |
| 907 | // \\/// test1 | |
| 908 | // \\// test2 | |
| 909 | // \\const e = f; | |
| 910 | // \\ | |
| 911 | // ); | |
| 912 | //} | |
| 913 | // | |
| 914 | //test "zig fmt: pointer of unknown length" { | |
| 915 | // try testCanonical( | |
| 916 | // \\fn foo(ptr: [*]u8) void {} | |
| 917 | // \\ | |
| 918 | // ); | |
| 919 | //} | |
| 920 | // | |
| 921 | //test "zig fmt: spaces around slice operator" { | |
| 922 | // try testCanonical( | |
| 923 | // \\var a = b[c..d]; | |
| 924 | // \\var a = b[c..d :0]; | |
| 925 | // \\var a = b[c + 1 .. d]; | |
| 926 | // \\var a = b[c + 1 ..]; | |
| 927 | // \\var a = b[c .. d + 1]; | |
| 928 | // \\var a = b[c .. d + 1 :0]; | |
| 929 | // \\var a = b[c.a..d.e]; | |
| 930 | // \\var a = b[c.a..d.e :0]; | |
| 931 | // \\ | |
| 932 | // ); | |
| 933 | //} | |
| 934 | // | |
| 935 | //test "zig fmt: async call in if condition" { | |
| 936 | // try testCanonical( | |
| 937 | // \\comptime { | |
| 938 | // \\ if (async b()) { | |
| 939 | // \\ a(); | |
| 940 | // \\ } | |
| 941 | // \\} | |
| 942 | // \\ | |
| 943 | // ); | |
| 944 | //} | |
| 945 | // | |
| 946 | //test "zig fmt: 2nd arg multiline string" { | |
| 947 | // try testCanonical( | |
| 948 | // \\comptime { | |
| 949 | // \\ cases.addAsm("hello world linux x86_64", | |
| 950 | // \\ \\.text | |
| 951 | // \\ , "Hello, world!\n"); | |
| 952 | // \\} | |
| 953 | // \\ | |
| 954 | // ); | |
| 955 | //} | |
| 956 | // | |
| 957 | //test "zig fmt: 2nd arg multiline string many args" { | |
| 958 | // try testCanonical( | |
| 959 | // \\comptime { | |
| 960 | // \\ cases.addAsm("hello world linux x86_64", | |
| 961 | // \\ \\.text | |
| 962 | // \\ , "Hello, world!\n", "Hello, world!\n"); | |
| 963 | // \\} | |
| 964 | // \\ | |
| 965 | // ); | |
| 966 | //} | |
| 967 | // | |
| 968 | //test "zig fmt: final arg multiline string" { | |
| 969 | // try testCanonical( | |
| 970 | // \\comptime { | |
| 971 | // \\ cases.addAsm("hello world linux x86_64", "Hello, world!\n", | |
| 972 | // \\ \\.text | |
| 973 | // \\ ); | |
| 974 | // \\} | |
| 975 | // \\ | |
| 976 | // ); | |
| 977 | //} | |
| 978 | // | |
| 979 | //test "zig fmt: if condition wraps" { | |
| 980 | // try testTransform( | |
| 981 | // \\comptime { | |
| 982 | // \\ if (cond and | |
| 983 | // \\ cond) { | |
| 984 | // \\ return x; | |
| 985 | // \\ } | |
| 986 | // \\ while (cond and | |
| 987 | // \\ cond) { | |
| 988 | // \\ return x; | |
| 989 | // \\ } | |
| 990 | // \\ if (a == b and | |
| 991 | // \\ c) { | |
| 992 | // \\ a = b; | |
| 993 | // \\ } | |
| 994 | // \\ while (a == b and | |
| 995 | // \\ c) { | |
| 996 | // \\ a = b; | |
| 997 | // \\ } | |
| 998 | // \\ if ((cond and | |
| 999 | // \\ cond)) { | |
| 1000 | // \\ return x; | |
| 1001 | // \\ } | |
| 1002 | // \\ while ((cond and | |
| 1003 | // \\ cond)) { | |
| 1004 | // \\ return x; | |
| 1005 | // \\ } | |
| 1006 | // \\ var a = if (a) |*f| x: { | |
| 1007 | // \\ break :x &a.b; | |
| 1008 | // \\ } else |err| err; | |
| 1009 | // \\ var a = if (cond and | |
| 1010 | // \\ cond) |*f| | |
| 1011 | // \\ x: { | |
| 1012 | // \\ break :x &a.b; | |
| 1013 | // \\ } else |err| err; | |
| 1014 | // \\} | |
| 1015 | // , | |
| 1016 | // \\comptime { | |
| 1017 | // \\ if (cond and | |
| 1018 | // \\ cond) | |
| 1019 | // \\ { | |
| 1020 | // \\ return x; | |
| 1021 | // \\ } | |
| 1022 | // \\ while (cond and | |
| 1023 | // \\ cond) | |
| 1024 | // \\ { | |
| 1025 | // \\ return x; | |
| 1026 | // \\ } | |
| 1027 | // \\ if (a == b and | |
| 1028 | // \\ c) | |
| 1029 | // \\ { | |
| 1030 | // \\ a = b; | |
| 1031 | // \\ } | |
| 1032 | // \\ while (a == b and | |
| 1033 | // \\ c) | |
| 1034 | // \\ { | |
| 1035 | // \\ a = b; | |
| 1036 | // \\ } | |
| 1037 | // \\ if ((cond and | |
| 1038 | // \\ cond)) | |
| 1039 | // \\ { | |
| 1040 | // \\ return x; | |
| 1041 | // \\ } | |
| 1042 | // \\ while ((cond and | |
| 1043 | // \\ cond)) | |
| 1044 | // \\ { | |
| 1045 | // \\ return x; | |
| 1046 | // \\ } | |
| 1047 | // \\ var a = if (a) |*f| x: { | |
| 1048 | // \\ break :x &a.b; | |
| 1049 | // \\ } else |err| err; | |
| 1050 | // \\ var a = if (cond and | |
| 1051 | // \\ cond) |*f| | |
| 1052 | // \\ x: { | |
| 1053 | // \\ break :x &a.b; | |
| 1054 | // \\ } else |err| err; | |
| 1055 | // \\} | |
| 1056 | // \\ | |
| 1057 | // ); | |
| 1058 | //} | |
| 1059 | // | |
| 1060 | //test "zig fmt: if condition has line break but must not wrap" { | |
| 1061 | // try testCanonical( | |
| 1062 | // \\comptime { | |
| 1063 | // \\ if (self.user_input_options.put( | |
| 1064 | // \\ name, | |
| 1065 | // \\ UserInputOption{ | |
| 1066 | // \\ .name = name, | |
| 1067 | // \\ .used = false, | |
| 1068 | // \\ }, | |
| 1069 | // \\ ) catch unreachable) |*prev_value| { | |
| 1070 | // \\ foo(); | |
| 1071 | // \\ bar(); | |
| 1072 | // \\ } | |
| 1073 | // \\ if (put( | |
| 1074 | // \\ a, | |
| 1075 | // \\ b, | |
| 1076 | // \\ )) { | |
| 1077 | // \\ foo(); | |
| 1078 | // \\ } | |
| 1079 | // \\} | |
| 1080 | // \\ | |
| 1081 | // ); | |
| 1082 | //} | |
| 1083 | // | |
| 1084 | //test "zig fmt: if condition has line break but must not wrap" { | |
| 1085 | // try testCanonical( | |
| 1086 | // \\comptime { | |
| 1087 | // \\ if (self.user_input_options.put(name, UserInputOption{ | |
| 1088 | // \\ .name = name, | |
| 1089 | // \\ .used = false, | |
| 1090 | // \\ }) catch unreachable) |*prev_value| { | |
| 1091 | // \\ foo(); | |
| 1092 | // \\ bar(); | |
| 1093 | // \\ } | |
| 1094 | // \\ if (put( | |
| 1095 | // \\ a, | |
| 1096 | // \\ b, | |
| 1097 | // \\ )) { | |
| 1098 | // \\ foo(); | |
| 1099 | // \\ } | |
| 1100 | // \\} | |
| 1101 | // \\ | |
| 1102 | // ); | |
| 1103 | //} | |
| 1104 | // | |
| 1105 | //test "zig fmt: function call with multiline argument" { | |
| 1106 | // try testCanonical( | |
| 1107 | // \\comptime { | |
| 1108 | // \\ self.user_input_options.put(name, UserInputOption{ | |
| 1109 | // \\ .name = name, | |
| 1110 | // \\ .used = false, | |
| 1111 | // \\ }); | |
| 1112 | // \\} | |
| 1113 | // \\ | |
| 1114 | // ); | |
| 1115 | //} | |
| 1116 | // | |
| 1117 | //test "zig fmt: same-line doc comment on variable declaration" { | |
| 1118 | // try testTransform( | |
| 1119 | // \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space | |
| 1120 | // \\pub const MAP_FILE = 0x0000; /// map from file (default) | |
| 1121 | // \\ | |
| 1122 | // \\pub const EMEDIUMTYPE = 124; /// Wrong medium type | |
| 1123 | // \\ | |
| 1124 | // \\// nameserver query return codes | |
| 1125 | // \\pub const ENSROK = 0; /// DNS server returned answer with no data | |
| 1126 | // , | |
| 1127 | // \\/// allocated from memory, swap space | |
| 1128 | // \\pub const MAP_ANONYMOUS = 0x1000; | |
| 1129 | // \\/// map from file (default) | |
| 1130 | // \\pub const MAP_FILE = 0x0000; | |
| 1131 | // \\ | |
| 1132 | // \\/// Wrong medium type | |
| 1133 | // \\pub const EMEDIUMTYPE = 124; | |
| 1134 | // \\ | |
| 1135 | // \\// nameserver query return codes | |
| 1136 | // \\/// DNS server returned answer with no data | |
| 1137 | // \\pub const ENSROK = 0; | |
| 1138 | // \\ | |
| 1139 | // ); | |
| 1140 | //} | |
| 1141 | // | |
| 1142 | //test "zig fmt: if-else with comment before else" { | |
| 1143 | // try testCanonical( | |
| 1144 | // \\comptime { | |
| 1145 | // \\ // cexp(finite|nan +- i inf|nan) = nan + i nan | |
| 1146 | // \\ if ((hx & 0x7fffffff) != 0x7f800000) { | |
| 1147 | // \\ return Complex(f32).new(y - y, y - y); | |
| 1148 | // \\ } // cexp(-inf +- i inf|nan) = 0 + i0 | |
| 1149 | // \\ else if (hx & 0x80000000 != 0) { | |
| 1150 | // \\ return Complex(f32).new(0, 0); | |
| 1151 | // \\ } // cexp(+inf +- i inf|nan) = inf + i nan | |
| 1152 | // \\ else { | |
| 1153 | // \\ return Complex(f32).new(x, y - y); | |
| 1154 | // \\ } | |
| 1155 | // \\} | |
| 1156 | // \\ | |
| 1157 | // ); | |
| 1158 | //} | |
| 1159 | // | |
| 1160 | //test "zig fmt: if nested" { | |
| 1161 | // try testCanonical( | |
| 1162 | // \\pub fn foo() void { | |
| 1163 | // \\ return if ((aInt & bInt) >= 0) | |
| 1164 | // \\ if (aInt < bInt) | |
| 1165 | // \\ GE_LESS | |
| 1166 | // \\ else if (aInt == bInt) | |
| 1167 | // \\ GE_EQUAL | |
| 1168 | // \\ else | |
| 1169 | // \\ GE_GREATER | |
| 1170 | // \\ else if (aInt > bInt) | |
| 1171 | // \\ GE_LESS | |
| 1172 | // \\ else if (aInt == bInt) | |
| 1173 | // \\ GE_EQUAL | |
| 1174 | // \\ else | |
| 1175 | // \\ GE_GREATER; | |
| 1176 | // \\} | |
| 1177 | // \\ | |
| 1178 | // ); | |
| 1179 | //} | |
| 1180 | // | |
| 1181 | //test "zig fmt: respect line breaks in if-else" { | |
| 1182 | // try testCanonical( | |
| 1183 | // \\comptime { | |
| 1184 | // \\ return if (cond) a else b; | |
| 1185 | // \\ return if (cond) | |
| 1186 | // \\ a | |
| 1187 | // \\ else | |
| 1188 | // \\ b; | |
| 1189 | // \\ return if (cond) | |
| 1190 | // \\ a | |
| 1191 | // \\ else if (cond) | |
| 1192 | // \\ b | |
| 1193 | // \\ else | |
| 1194 | // \\ c; | |
| 1195 | // \\} | |
| 1196 | // \\ | |
| 1197 | // ); | |
| 1198 | //} | |
| 1199 | // | |
| 1200 | //test "zig fmt: respect line breaks after infix operators" { | |
| 1201 | // try testCanonical( | |
| 1202 | // \\comptime { | |
| 1203 | // \\ self.crc = | |
| 1204 | // \\ lookup_tables[0][p[7]] ^ | |
| 1205 | // \\ lookup_tables[1][p[6]] ^ | |
| 1206 | // \\ lookup_tables[2][p[5]] ^ | |
| 1207 | // \\ lookup_tables[3][p[4]] ^ | |
| 1208 | // \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^ | |
| 1209 | // \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^ | |
| 1210 | // \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^ | |
| 1211 | // \\ lookup_tables[7][@truncate(u8, self.crc >> 0)]; | |
| 1212 | // \\} | |
| 1213 | // \\ | |
| 1214 | // ); | |
| 1215 | //} | |
| 1216 | // | |
| 1217 | //test "zig fmt: fn decl with trailing comma" { | |
| 1218 | // try testTransform( | |
| 1219 | // \\fn foo(a: i32, b: i32,) void {} | |
| 1220 | // , | |
| 1221 | // \\fn foo( | |
| 1222 | // \\ a: i32, | |
| 1223 | // \\ b: i32, | |
| 1224 | // \\) void {} | |
| 1225 | // \\ | |
| 1226 | // ); | |
| 1227 | //} | |
| 1228 | // | |
| 1229 | //test "zig fmt: enum decl with no trailing comma" { | |
| 1230 | // try testTransform( | |
| 1231 | // \\const StrLitKind = enum {Normal, C}; | |
| 1232 | // , | |
| 1233 | // \\const StrLitKind = enum { Normal, C }; | |
| 1234 | // \\ | |
| 1235 | // ); | |
| 1236 | //} | |
| 1237 | // | |
| 1238 | //test "zig fmt: switch comment before prong" { | |
| 1239 | // try testCanonical( | |
| 1240 | // \\comptime { | |
| 1241 | // \\ switch (a) { | |
| 1242 | // \\ // hi | |
| 1243 | // \\ 0 => {}, | |
| 1244 | // \\ } | |
| 1245 | // \\} | |
| 1246 | // \\ | |
| 1247 | // ); | |
| 1248 | //} | |
| 1249 | // | |
| 1250 | //test "zig fmt: struct literal no trailing comma" { | |
| 1251 | // try testTransform( | |
| 1252 | // \\const a = foo{ .x = 1, .y = 2 }; | |
| 1253 | // \\const a = foo{ .x = 1, | |
| 1254 | // \\ .y = 2 }; | |
| 1255 | // , | |
| 1256 | // \\const a = foo{ .x = 1, .y = 2 }; | |
| 1257 | // \\const a = foo{ | |
| 1258 | // \\ .x = 1, | |
| 1259 | // \\ .y = 2, | |
| 1260 | // \\}; | |
| 1261 | // \\ | |
| 1262 | // ); | |
| 1263 | //} | |
| 1264 | // | |
| 1265 | //test "zig fmt: struct literal containing a multiline expression" { | |
| 1266 | // try testTransform( | |
| 1267 | // \\const a = A{ .x = if (f1()) 10 else 20 }; | |
| 1268 | // \\const a = A{ .x = if (f1()) 10 else 20, }; | |
| 1269 | // \\const a = A{ .x = if (f1()) | |
| 1270 | // \\ 10 else 20 }; | |
| 1271 | // \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 }; | |
| 1272 | // \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100, }; | |
| 1273 | // \\const a = A{ .x = if (f1()) | |
| 1274 | // \\ 10 else 20}; | |
| 1275 | // \\const a = A{ .x = switch(g) {0 => "ok", else => "no"} }; | |
| 1276 | // \\ | |
| 1277 | // , | |
| 1278 | // \\const a = A{ .x = if (f1()) 10 else 20 }; | |
| 1279 | // \\const a = A{ | |
| 1280 | // \\ .x = if (f1()) 10 else 20, | |
| 1281 | // \\}; | |
| 1282 | // \\const a = A{ | |
| 1283 | // \\ .x = if (f1()) | |
| 1284 | // \\ 10 | |
| 1285 | // \\ else | |
| 1286 | // \\ 20, | |
| 1287 | // \\}; | |
| 1288 | // \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 }; | |
| 1289 | // \\const a = A{ | |
| 1290 | // \\ .x = if (f1()) 10 else 20, | |
| 1291 | // \\ .y = f2() + 100, | |
| 1292 | // \\}; | |
| 1293 | // \\const a = A{ | |
| 1294 | // \\ .x = if (f1()) | |
| 1295 | // \\ 10 | |
| 1296 | // \\ else | |
| 1297 | // \\ 20, | |
| 1298 | // \\}; | |
| 1299 | // \\const a = A{ | |
| 1300 | // \\ .x = switch (g) { | |
| 1301 | // \\ 0 => "ok", | |
| 1302 | // \\ else => "no", | |
| 1303 | // \\ }, | |
| 1304 | // \\}; | |
| 1305 | // \\ | |
| 1306 | // ); | |
| 1307 | //} | |
| 1308 | // | |
| 1309 | //test "zig fmt: array literal with hint" { | |
| 1310 | // try testTransform( | |
| 1311 | // \\const a = []u8{ | |
| 1312 | // \\ 1, 2, // | |
| 1313 | // \\ 3, | |
| 1314 | // \\ 4, | |
| 1315 | // \\ 5, | |
| 1316 | // \\ 6, | |
| 1317 | // \\ 7 }; | |
| 1318 | // \\const a = []u8{ | |
| 1319 | // \\ 1, 2, // | |
| 1320 | // \\ 3, | |
| 1321 | // \\ 4, | |
| 1322 | // \\ 5, | |
| 1323 | // \\ 6, | |
| 1324 | // \\ 7, 8 }; | |
| 1325 | // \\const a = []u8{ | |
| 1326 | // \\ 1, 2, // | |
| 1327 | // \\ 3, | |
| 1328 | // \\ 4, | |
| 1329 | // \\ 5, | |
| 1330 | // \\ 6, // blah | |
| 1331 | // \\ 7, 8 }; | |
| 1332 | // \\const a = []u8{ | |
| 1333 | // \\ 1, 2, // | |
| 1334 | // \\ 3, // | |
| 1335 | // \\ 4, | |
| 1336 | // \\ 5, | |
| 1337 | // \\ 6, | |
| 1338 | // \\ 7 }; | |
| 1339 | // \\const a = []u8{ | |
| 1340 | // \\ 1, | |
| 1341 | // \\ 2, | |
| 1342 | // \\ 3, 4, // | |
| 1343 | // \\ 5, 6, // | |
| 1344 | // \\ 7, 8, // | |
| 1345 | // \\}; | |
| 1346 | // , | |
| 1347 | // \\const a = []u8{ | |
| 1348 | // \\ 1, 2, | |
| 1349 | // \\ 3, 4, | |
| 1350 | // \\ 5, 6, | |
| 1351 | // \\ 7, | |
| 1352 | // \\}; | |
| 1353 | // \\const a = []u8{ | |
| 1354 | // \\ 1, 2, | |
| 1355 | // \\ 3, 4, | |
| 1356 | // \\ 5, 6, | |
| 1357 | // \\ 7, 8, | |
| 1358 | // \\}; | |
| 1359 | // \\const a = []u8{ | |
| 1360 | // \\ 1, 2, | |
| 1361 | // \\ 3, 4, | |
| 1362 | // \\ 5, | |
| 1363 | // \\ 6, // blah | |
| 1364 | // \\ 7, | |
| 1365 | // \\ 8, | |
| 1366 | // \\}; | |
| 1367 | // \\const a = []u8{ | |
| 1368 | // \\ 1, 2, | |
| 1369 | // \\ 3, // | |
| 1370 | // \\ 4, | |
| 1371 | // \\ 5, 6, | |
| 1372 | // \\ 7, | |
| 1373 | // \\}; | |
| 1374 | // \\const a = []u8{ | |
| 1375 | // \\ 1, | |
| 1376 | // \\ 2, | |
| 1377 | // \\ 3, | |
| 1378 | // \\ 4, | |
| 1379 | // \\ 5, | |
| 1380 | // \\ 6, | |
| 1381 | // \\ 7, | |
| 1382 | // \\ 8, | |
| 1383 | // \\}; | |
| 1384 | // \\ | |
| 1385 | // ); | |
| 1386 | //} | |
| 1387 | // | |
| 1388 | //test "zig fmt: array literal veritical column alignment" { | |
| 1389 | // try testTransform( | |
| 1390 | // \\const a = []u8{ | |
| 1391 | // \\ 1000, 200, | |
| 1392 | // \\ 30, 4, | |
| 1393 | // \\ 50000, 60 | |
| 1394 | // \\}; | |
| 1395 | // \\const a = []u8{0, 1, 2, 3, 40, | |
| 1396 | // \\ 4,5,600,7, | |
| 1397 | // \\ 80, | |
| 1398 | // \\ 9, 10, 11, 0, 13, 14, 15}; | |
| 1399 | // \\ | |
| 1400 | // , | |
| 1401 | // \\const a = []u8{ | |
| 1402 | // \\ 1000, 200, | |
| 1403 | // \\ 30, 4, | |
| 1404 | // \\ 50000, 60, | |
| 1405 | // \\}; | |
| 1406 | // \\const a = []u8{ | |
| 1407 | // \\ 0, 1, 2, 3, 40, | |
| 1408 | // \\ 4, 5, 600, 7, 80, | |
| 1409 | // \\ 9, 10, 11, 0, 13, | |
| 1410 | // \\ 14, 15, | |
| 1411 | // \\}; | |
| 1412 | // \\ | |
| 1413 | // ); | |
| 1414 | //} | |
| 1415 | // | |
| 1416 | //test "zig fmt: multiline string with backslash at end of line" { | |
| 1417 | // try testCanonical( | |
| 1418 | // \\comptime { | |
| 1419 | // \\ err( | |
| 1420 | // \\ \\\ | |
| 1421 | // \\ ); | |
| 1422 | // \\} | |
| 1423 | // \\ | |
| 1424 | // ); | |
| 1425 | //} | |
| 1426 | // | |
| 1427 | //test "zig fmt: multiline string parameter in fn call with trailing comma" { | |
| 1428 | // try testCanonical( | |
| 1429 | // \\fn foo() void { | |
| 1430 | // \\ try stdout.print( | |
| 1431 | // \\ \\ZIG_CMAKE_BINARY_DIR {} | |
| 1432 | // \\ \\ZIG_C_HEADER_FILES {} | |
| 1433 | // \\ \\ZIG_DIA_GUIDS_LIB {} | |
| 1434 | // \\ \\ | |
| 1435 | // \\ , | |
| 1436 | // \\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR), | |
| 1437 | // \\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER), | |
| 1438 | // \\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB), | |
| 1439 | // \\ ); | |
| 1440 | // \\} | |
| 1441 | // \\ | |
| 1442 | // ); | |
| 1443 | //} | |
| 1444 | // | |
| 1445 | //test "zig fmt: trailing comma on fn call" { | |
| 1446 | // try testCanonical( | |
| 1447 | // \\comptime { | |
| 1448 | // \\ var module = try Module.create( | |
| 1449 | // \\ allocator, | |
| 1450 | // \\ zig_lib_dir, | |
| 1451 | // \\ full_cache_dir, | |
| 1452 | // \\ ); | |
| 1453 | // \\} | |
| 1454 | // \\ | |
| 1455 | // ); | |
| 1456 | //} | |
| 1457 | // | |
| 1458 | //test "zig fmt: multi line arguments without last comma" { | |
| 1459 | // try testTransform( | |
| 1460 | // \\pub fn foo( | |
| 1461 | // \\ a: usize, | |
| 1462 | // \\ b: usize, | |
| 1463 | // \\ c: usize, | |
| 1464 | // \\ d: usize | |
| 1465 | // \\) usize { | |
| 1466 | // \\ return a + b + c + d; | |
| 1467 | // \\} | |
| 1468 | // \\ | |
| 1469 | // , | |
| 1470 | // \\pub fn foo(a: usize, b: usize, c: usize, d: usize) usize { | |
| 1471 | // \\ return a + b + c + d; | |
| 1472 | // \\} | |
| 1473 | // \\ | |
| 1474 | // ); | |
| 1475 | //} | |
| 1476 | // | |
| 1477 | //test "zig fmt: empty block with only comment" { | |
| 1478 | // try testCanonical( | |
| 1479 | // \\comptime { | |
| 1480 | // \\ { | |
| 1481 | // \\ // comment | |
| 1482 | // \\ } | |
| 1483 | // \\} | |
| 1484 | // \\ | |
| 1485 | // ); | |
| 1486 | //} | |
| 1487 | // | |
| 1488 | //test "zig fmt: no trailing comma on struct decl" { | |
| 1489 | // try testCanonical( | |
| 1490 | // \\const RoundParam = struct { | |
| 1491 | // \\ k: usize, s: u32, t: u32 | |
| 1492 | // \\}; | |
| 1493 | // \\ | |
| 1494 | // ); | |
| 1495 | //} | |
| 1496 | // | |
| 1497 | //test "zig fmt: extra newlines at the end" { | |
| 1498 | // try testTransform( | |
| 1499 | // \\const a = b; | |
| 1500 | // \\ | |
| 1501 | // \\ | |
| 1502 | // \\ | |
| 1503 | // , | |
| 1504 | // \\const a = b; | |
| 1505 | // \\ | |
| 1506 | // ); | |
| 1507 | //} | |
| 1508 | // | |
| 1509 | //test "zig fmt: simple asm" { | |
| 1510 | // try testTransform( | |
| 1511 | // \\comptime { | |
| 1512 | // \\ asm volatile ( | |
| 1513 | // \\ \\.globl aoeu; | |
| 1514 | // \\ \\.type aoeu, @function; | |
| 1515 | // \\ \\.set aoeu, derp; | |
| 1516 | // \\ ); | |
| 1517 | // \\ | |
| 1518 | // \\ asm ("not real assembly" | |
| 1519 | // \\ :[a] "x" (x),); | |
| 1520 | // \\ asm ("not real assembly" | |
| 1521 | // \\ :[a] "x" (->i32),:[a] "x" (1),); | |
| 1522 | // \\ asm ("still not real assembly" | |
| 1523 | // \\ :::"a","b",); | |
| 1524 | // \\} | |
| 1525 | // , | |
| 1526 | // \\comptime { | |
| 1527 | // \\ asm volatile ( | |
| 1528 | // \\ \\.globl aoeu; | |
| 1529 | // \\ \\.type aoeu, @function; | |
| 1530 | // \\ \\.set aoeu, derp; | |
| 1531 | // \\ ); | |
| 1532 | // \\ | |
| 1533 | // \\ asm ("not real assembly" | |
| 1534 | // \\ : [a] "x" (x) | |
| 1535 | // \\ ); | |
| 1536 | // \\ asm ("not real assembly" | |
| 1537 | // \\ : [a] "x" (-> i32) | |
| 1538 | // \\ : [a] "x" (1) | |
| 1539 | // \\ ); | |
| 1540 | // \\ asm ("still not real assembly" | |
| 1541 | // \\ : | |
| 1542 | // \\ : | |
| 1543 | // \\ : "a", "b" | |
| 1544 | // \\ ); | |
| 1545 | // \\} | |
| 1546 | // \\ | |
| 1547 | // ); | |
| 1548 | //} | |
| 1549 | // | |
| 1550 | //test "zig fmt: nested struct literal with one item" { | |
| 1551 | // try testCanonical( | |
| 1552 | // \\const a = foo{ | |
| 1553 | // \\ .item = bar{ .a = b }, | |
| 1554 | // \\}; | |
| 1555 | // \\ | |
| 1556 | // ); | |
| 1557 | //} | |
| 1558 | // | |
| 1559 | //test "zig fmt: switch cases trailing comma" { | |
| 1560 | // try testTransform( | |
| 1561 | // \\fn switch_cases(x: i32) void { | |
| 1562 | // \\ switch (x) { | |
| 1563 | // \\ 1,2,3 => {}, | |
| 1564 | // \\ 4,5, => {}, | |
| 1565 | // \\ 6... 8, => {}, | |
| 1566 | // \\ else => {}, | |
| 1567 | // \\ } | |
| 1568 | // \\} | |
| 1569 | // , | |
| 1570 | // \\fn switch_cases(x: i32) void { | |
| 1571 | // \\ switch (x) { | |
| 1572 | // \\ 1, 2, 3 => {}, | |
| 1573 | // \\ 4, | |
| 1574 | // \\ 5, | |
| 1575 | // \\ => {}, | |
| 1576 | // \\ 6...8 => {}, | |
| 1577 | // \\ else => {}, | |
| 1578 | // \\ } | |
| 1579 | // \\} | |
| 1580 | // \\ | |
| 1581 | // ); | |
| 1582 | //} | |
| 1583 | // | |
| 1584 | //test "zig fmt: slice align" { | |
| 1585 | // try testCanonical( | |
| 1586 | // \\const A = struct { | |
| 1587 | // \\ items: []align(A) T, | |
| 1588 | // \\}; | |
| 1589 | // \\ | |
| 1590 | // ); | |
| 1591 | //} | |
| 1592 | // | |
| 1593 | //test "zig fmt: add trailing comma to array literal" { | |
| 1594 | // try testTransform( | |
| 1595 | // \\comptime { | |
| 1596 | // \\ return []u16{'m', 's', 'y', 's', '-' // hi | |
| 1597 | // \\ }; | |
| 1598 | // \\ return []u16{'m', 's', 'y', 's', | |
| 1599 | // \\ '-'}; | |
| 1600 | // \\ return []u16{'m', 's', 'y', 's', '-'}; | |
| 1601 | // \\} | |
| 1602 | // , | |
| 1603 | // \\comptime { | |
| 1604 | // \\ return []u16{ | |
| 1605 | // \\ 'm', 's', 'y', 's', '-', // hi | |
| 1606 | // \\ }; | |
| 1607 | // \\ return []u16{ | |
| 1608 | // \\ 'm', 's', 'y', 's', | |
| 1609 | // \\ '-', | |
| 1610 | // \\ }; | |
| 1611 | // \\ return []u16{ 'm', 's', 'y', 's', '-' }; | |
| 1612 | // \\} | |
| 1613 | // \\ | |
| 1614 | // ); | |
| 1615 | //} | |
| 1616 | // | |
| 1617 | //test "zig fmt: first thing in file is line comment" { | |
| 1618 | // try testCanonical( | |
| 1619 | // \\// Introspection and determination of system libraries needed by zig. | |
| 1620 | // \\ | |
| 1621 | // \\// Introspection and determination of system libraries needed by zig. | |
| 1622 | // \\ | |
| 1623 | // \\const std = @import("std"); | |
| 1624 | // \\ | |
| 1625 | // ); | |
| 1626 | //} | |
| 1627 | // | |
| 1628 | //test "zig fmt: line comment after doc comment" { | |
| 1629 | // try testCanonical( | |
| 1630 | // \\/// doc comment | |
| 1631 | // \\// line comment | |
| 1632 | // \\fn foo() void {} | |
| 1633 | // \\ | |
| 1634 | // ); | |
| 1635 | //} | |
| 1636 | // | |
| 1637 | //test "zig fmt: float literal with exponent" { | |
| 1638 | // try testCanonical( | |
| 1639 | // \\test "bit field alignment" { | |
| 1640 | // \\ assert(@TypeOf(&blah.b) == *align(1:3:6) const u3); | |
| 1641 | // \\} | |
| 1642 | // \\ | |
| 1643 | // ); | |
| 1644 | //} | |
| 1645 | // | |
| 1646 | //test "zig fmt: float literal with exponent" { | |
| 1647 | // try testCanonical( | |
| 1648 | // \\test "aoeu" { | |
| 1649 | // \\ switch (state) { | |
| 1650 | // \\ TermState.Start => switch (c) { | |
| 1651 | // \\ '\x1b' => state = TermState.Escape, | |
| 1652 | // \\ else => try out.writeByte(c), | |
| 1653 | // \\ }, | |
| 1654 | // \\ } | |
| 1655 | // \\} | |
| 1656 | // \\ | |
| 1657 | // ); | |
| 1658 | //} | |
| 1659 | //test "zig fmt: float literal with exponent" { | |
| 1660 | // try testCanonical( | |
| 1661 | // \\pub const f64_true_min = 4.94065645841246544177e-324; | |
| 1662 | // \\const threshold = 0x1.a827999fcef32p+1022; | |
| 1663 | // \\ | |
| 1664 | // ); | |
| 1665 | //} | |
| 1666 | // | |
| 1667 | //test "zig fmt: if-else end of comptime" { | |
| 1668 | // try testCanonical( | |
| 1669 | // \\comptime { | |
| 1670 | // \\ if (a) { | |
| 1671 | // \\ b(); | |
| 1672 | // \\ } else { | |
| 1673 | // \\ b(); | |
| 1674 | // \\ } | |
| 1675 | // \\} | |
| 1676 | // \\ | |
| 1677 | // ); | |
| 1678 | //} | |
| 1679 | // | |
| 1680 | //test "zig fmt: nested blocks" { | |
| 1681 | // try testCanonical( | |
| 1682 | // \\comptime { | |
| 1683 | // \\ { | |
| 1684 | // \\ { | |
| 1685 | // \\ { | |
| 1686 | // \\ a(); | |
| 1687 | // \\ } | |
| 1688 | // \\ } | |
| 1689 | // \\ } | |
| 1690 | // \\} | |
| 1691 | // \\ | |
| 1692 | // ); | |
| 1693 | //} | |
| 1694 | // | |
| 1695 | //test "zig fmt: block with same line comment after end brace" { | |
| 1696 | // try testCanonical( | |
| 1697 | // \\comptime { | |
| 1698 | // \\ { | |
| 1699 | // \\ b(); | |
| 1700 | // \\ } // comment | |
| 1701 | // \\} | |
| 1702 | // \\ | |
| 1703 | // ); | |
| 1704 | //} | |
| 1705 | // | |
| 1706 | //test "zig fmt: statements with comment between" { | |
| 1707 | // try testCanonical( | |
| 1708 | // \\comptime { | |
| 1709 | // \\ a = b; | |
| 1710 | // \\ // comment | |
| 1711 | // \\ a = b; | |
| 1712 | // \\} | |
| 1713 | // \\ | |
| 1714 | // ); | |
| 1715 | //} | |
| 1716 | // | |
| 1717 | //test "zig fmt: statements with empty line between" { | |
| 1718 | // try testCanonical( | |
| 1719 | // \\comptime { | |
| 1720 | // \\ a = b; | |
| 1721 | // \\ | |
| 1722 | // \\ a = b; | |
| 1723 | // \\} | |
| 1724 | // \\ | |
| 1725 | // ); | |
| 1726 | //} | |
| 1727 | // | |
| 1728 | //test "zig fmt: ptr deref operator and unwrap optional operator" { | |
| 1729 | // try testCanonical( | |
| 1730 | // \\const a = b.*; | |
| 1731 | // \\const a = b.?; | |
| 1732 | // \\ | |
| 1733 | // ); | |
| 1734 | //} | |
| 1735 | // | |
| 1736 | //test "zig fmt: comment after if before another if" { | |
| 1737 | // try testCanonical( | |
| 1738 | // \\test "aoeu" { | |
| 1739 | // \\ // comment | |
| 1740 | // \\ if (x) { | |
| 1741 | // \\ bar(); | |
| 1742 | // \\ } | |
| 1743 | // \\} | |
| 1744 | // \\ | |
| 1745 | // \\test "aoeu" { | |
| 1746 | // \\ if (x) { | |
| 1747 | // \\ foo(); | |
| 1748 | // \\ } | |
| 1749 | // \\ // comment | |
| 1750 | // \\ if (x) { | |
| 1751 | // \\ bar(); | |
| 1752 | // \\ } | |
| 1753 | // \\} | |
| 1754 | // \\ | |
| 1755 | // ); | |
| 1756 | //} | |
| 1757 | // | |
| 1758 | //test "zig fmt: line comment between if block and else keyword" { | |
| 1759 | // try testCanonical( | |
| 1760 | // \\test "aoeu" { | |
| 1761 | // \\ // cexp(finite|nan +- i inf|nan) = nan + i nan | |
| 1762 | // \\ if ((hx & 0x7fffffff) != 0x7f800000) { | |
| 1763 | // \\ return Complex(f32).new(y - y, y - y); | |
| 1764 | // \\ } | |
| 1765 | // \\ // cexp(-inf +- i inf|nan) = 0 + i0 | |
| 1766 | // \\ else if (hx & 0x80000000 != 0) { | |
| 1767 | // \\ return Complex(f32).new(0, 0); | |
| 1768 | // \\ } | |
| 1769 | // \\ // cexp(+inf +- i inf|nan) = inf + i nan | |
| 1770 | // \\ // another comment | |
| 1771 | // \\ else { | |
| 1772 | // \\ return Complex(f32).new(x, y - y); | |
| 1773 | // \\ } | |
| 1774 | // \\} | |
| 1775 | // \\ | |
| 1776 | // ); | |
| 1777 | //} | |
| 1778 | // | |
| 1779 | //test "zig fmt: same line comments in expression" { | |
| 1780 | // try testCanonical( | |
| 1781 | // \\test "aoeu" { | |
| 1782 | // \\ const x = ( // a | |
| 1783 | // \\ 0 // b | |
| 1784 | // \\ ); // c | |
| 1785 | // \\} | |
| 1786 | // \\ | |
| 1787 | // ); | |
| 1788 | //} | |
| 1789 | // | |
| 1790 | //test "zig fmt: add comma on last switch prong" { | |
| 1791 | // try testTransform( | |
| 1792 | // \\test "aoeu" { | |
| 1793 | // \\switch (self.init_arg_expr) { | |
| 1794 | // \\ InitArg.Type => |t| { }, | |
| 1795 | // \\ InitArg.None, | |
| 1796 | // \\ InitArg.Enum => { } | |
| 1797 | // \\} | |
| 1798 | // \\ switch (self.init_arg_expr) { | |
| 1799 | // \\ InitArg.Type => |t| { }, | |
| 1800 | // \\ InitArg.None, | |
| 1801 | // \\ InitArg.Enum => { }//line comment | |
| 1802 | // \\ } | |
| 1803 | // \\} | |
| 1804 | // , | |
| 1805 | // \\test "aoeu" { | |
| 1806 | // \\ switch (self.init_arg_expr) { | |
| 1807 | // \\ InitArg.Type => |t| {}, | |
| 1808 | // \\ InitArg.None, InitArg.Enum => {}, | |
| 1809 | // \\ } | |
| 1810 | // \\ switch (self.init_arg_expr) { | |
| 1811 | // \\ InitArg.Type => |t| {}, | |
| 1812 | // \\ InitArg.None, InitArg.Enum => {}, //line comment | |
| 1813 | // \\ } | |
| 1814 | // \\} | |
| 1815 | // \\ | |
| 1816 | // ); | |
| 1817 | //} | |
| 1818 | // | |
| 1819 | //test "zig fmt: same-line comment after a statement" { | |
| 1820 | // try testCanonical( | |
| 1821 | // \\test "" { | |
| 1822 | // \\ a = b; | |
| 1823 | // \\ debug.assert(H.digest_size <= H.block_size); // HMAC makes this assumption | |
| 1824 | // \\ a = b; | |
| 1825 | // \\} | |
| 1826 | // \\ | |
| 1827 | // ); | |
| 1828 | //} | |
| 1829 | // | |
| 1830 | //test "zig fmt: same-line comment after var decl in struct" { | |
| 1831 | // try testCanonical( | |
| 1832 | // \\pub const vfs_cap_data = extern struct { | |
| 1833 | // \\ const Data = struct {}; // when on disk. | |
| 1834 | // \\}; | |
| 1835 | // \\ | |
| 1836 | // ); | |
| 1837 | //} | |
| 1838 | // | |
| 1839 | //test "zig fmt: same-line comment after field decl" { | |
| 1840 | // try testCanonical( | |
| 1841 | // \\pub const dirent = extern struct { | |
| 1842 | // \\ d_name: u8, | |
| 1843 | // \\ d_name: u8, // comment 1 | |
| 1844 | // \\ d_name: u8, | |
| 1845 | // \\ d_name: u8, // comment 2 | |
| 1846 | // \\ d_name: u8, | |
| 1847 | // \\}; | |
| 1848 | // \\ | |
| 1849 | // ); | |
| 1850 | //} | |
| 1851 | // | |
| 1852 | //test "zig fmt: same-line comment after switch prong" { | |
| 1853 | // try testCanonical( | |
| 1854 | // \\test "" { | |
| 1855 | // \\ switch (err) { | |
| 1856 | // \\ error.PathAlreadyExists => {}, // comment 2 | |
| 1857 | // \\ else => return err, // comment 1 | |
| 1858 | // \\ } | |
| 1859 | // \\} | |
| 1860 | // \\ | |
| 1861 | // ); | |
| 1862 | //} | |
| 1863 | // | |
| 1864 | //test "zig fmt: same-line comment after non-block if expression" { | |
| 1865 | // try testCanonical( | |
| 1866 | // \\comptime { | |
| 1867 | // \\ if (sr > n_uword_bits - 1) // d > r | |
| 1868 | // \\ return 0; | |
| 1869 | // \\} | |
| 1870 | // \\ | |
| 1871 | // ); | |
| 1872 | //} | |
| 1873 | // | |
| 1874 | //test "zig fmt: same-line comment on comptime expression" { | |
| 1875 | // try testCanonical( | |
| 1876 | // \\test "" { | |
| 1877 | // \\ comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt | |
| 1878 | // \\} | |
| 1879 | // \\ | |
| 1880 | // ); | |
| 1881 | //} | |
| 1882 | // | |
| 1883 | //test "zig fmt: switch with empty body" { | |
| 1884 | // try testCanonical( | |
| 1885 | // \\test "" { | |
| 1886 | // \\ foo() catch |err| switch (err) {}; | |
| 1887 | // \\} | |
| 1888 | // \\ | |
| 1889 | // ); | |
| 1890 | //} | |
| 1891 | // | |
| 1892 | //test "zig fmt: line comments in struct initializer" { | |
| 1893 | // try testCanonical( | |
| 1894 | // \\fn foo() void { | |
| 1895 | // \\ return Self{ | |
| 1896 | // \\ .a = b, | |
| 1897 | // \\ | |
| 1898 | // \\ // Initialize these two fields to buffer_size so that | |
| 1899 | // \\ // in `readFn` we treat the state as being able to read | |
| 1900 | // \\ .start_index = buffer_size, | |
| 1901 | // \\ .end_index = buffer_size, | |
| 1902 | // \\ | |
| 1903 | // \\ // middle | |
| 1904 | // \\ | |
| 1905 | // \\ .a = b, | |
| 1906 | // \\ | |
| 1907 | // \\ // end | |
| 1908 | // \\ }; | |
| 1909 | // \\} | |
| 1910 | // \\ | |
| 1911 | // ); | |
| 1912 | //} | |
| 1913 | // | |
| 1914 | //test "zig fmt: first line comment in struct initializer" { | |
| 1915 | // try testCanonical( | |
| 1916 | // \\pub fn acquire(self: *Self) HeldLock { | |
| 1917 | // \\ return HeldLock{ | |
| 1918 | // \\ // guaranteed allocation elision | |
| 1919 | // \\ .held = self.lock.acquire(), | |
| 1920 | // \\ .value = &self.private_data, | |
| 1921 | // \\ }; | |
| 1922 | // \\} | |
| 1923 | // \\ | |
| 1924 | // ); | |
| 1925 | //} | |
| 1926 | // | |
| 1927 | //test "zig fmt: doc comments before struct field" { | |
| 1928 | // try testCanonical( | |
| 1929 | // \\pub const Allocator = struct { | |
| 1930 | // \\ /// Allocate byte_count bytes and return them in a slice, with the | |
| 1931 | // \\ /// slice's pointer aligned at least to alignment bytes. | |
| 1932 | // \\ allocFn: fn () void, | |
| 1933 | // \\}; | |
| 1934 | // \\ | |
| 1935 | // ); | |
| 1936 | //} | |
| 1937 | // | |
| 1938 | //test "zig fmt: error set declaration" { | |
| 1939 | // try testCanonical( | |
| 1940 | // \\const E = error{ | |
| 1941 | // \\ A, | |
| 1942 | // \\ B, | |
| 1943 | // \\ | |
| 1944 | // \\ C, | |
| 1945 | // \\}; | |
| 1946 | // \\ | |
| 1947 | // \\const Error = error{ | |
| 1948 | // \\ /// no more memory | |
| 1949 | // \\ OutOfMemory, | |
| 1950 | // \\}; | |
| 1951 | // \\ | |
| 1952 | // \\const Error = error{ | |
| 1953 | // \\ /// no more memory | |
| 1954 | // \\ OutOfMemory, | |
| 1955 | // \\ | |
| 1956 | // \\ /// another | |
| 1957 | // \\ Another, | |
| 1958 | // \\ | |
| 1959 | // \\ // end | |
| 1960 | // \\}; | |
| 1961 | // \\ | |
| 1962 | // \\const Error = error{OutOfMemory}; | |
| 1963 | // \\const Error = error{}; | |
| 1964 | // \\ | |
| 1965 | // \\const Error = error{ OutOfMemory, OutOfTime }; | |
| 1966 | // \\ | |
| 1967 | // ); | |
| 1968 | //} | |
| 1969 | // | |
| 1970 | //test "zig fmt: union(enum(u32)) with assigned enum values" { | |
| 1971 | // try testCanonical( | |
| 1972 | // \\const MultipleChoice = union(enum(u32)) { | |
| 1973 | // \\ A = 20, | |
| 1974 | // \\ B = 40, | |
| 1975 | // \\ C = 60, | |
| 1976 | // \\ D = 1000, | |
| 1977 | // \\}; | |
| 1978 | // \\ | |
| 1979 | // ); | |
| 1980 | //} | |
| 1981 | // | |
| 1982 | //test "zig fmt: resume from suspend block" { | |
| 1983 | // try testCanonical( | |
| 1984 | // \\fn foo() void { | |
| 1985 | // \\ suspend { | |
| 1986 | // \\ resume @frame(); | |
| 1987 | // \\ } | |
| 1988 | // \\} | |
| 1989 | // \\ | |
| 1990 | // ); | |
| 1991 | //} | |
| 1992 | // | |
| 1993 | //test "zig fmt: comments before error set decl" { | |
| 1994 | // try testCanonical( | |
| 1995 | // \\const UnexpectedError = error{ | |
| 1996 | // \\ /// The Operating System returned an undocumented error code. | |
| 1997 | // \\ Unexpected, | |
| 1998 | // \\ // another | |
| 1999 | // \\ Another, | |
| 2000 | // \\ | |
| 2001 | // \\ // in between | |
| 2002 | // \\ | |
| 2003 | // \\ // at end | |
| 2004 | // \\}; | |
| 2005 | // \\ | |
| 2006 | // ); | |
| 2007 | //} | |
| 2008 | // | |
| 2009 | //test "zig fmt: comments before switch prong" { | |
| 2010 | // try testCanonical( | |
| 2011 | // \\test "" { | |
| 2012 | // \\ switch (err) { | |
| 2013 | // \\ error.PathAlreadyExists => continue, | |
| 2014 | // \\ | |
| 2015 | // \\ // comment 1 | |
| 2016 | // \\ | |
| 2017 | // \\ // comment 2 | |
| 2018 | // \\ else => return err, | |
| 2019 | // \\ // at end | |
| 2020 | // \\ } | |
| 2021 | // \\} | |
| 2022 | // \\ | |
| 2023 | // ); | |
| 2024 | //} | |
| 2025 | // | |
| 2026 | //test "zig fmt: comments before var decl in struct" { | |
| 2027 | // try testCanonical( | |
| 2028 | // \\pub const vfs_cap_data = extern struct { | |
| 2029 | // \\ // All of these are mandated as little endian | |
| 2030 | // \\ // when on disk. | |
| 2031 | // \\ const Data = struct { | |
| 2032 | // \\ permitted: u32, | |
| 2033 | // \\ inheritable: u32, | |
| 2034 | // \\ }; | |
| 2035 | // \\ | |
| 2036 | // \\ // in between | |
| 2037 | // \\ | |
| 2038 | // \\ /// All of these are mandated as little endian | |
| 2039 | // \\ /// when on disk. | |
| 2040 | // \\ const Data = struct { | |
| 2041 | // \\ permitted: u32, | |
| 2042 | // \\ inheritable: u32, | |
| 2043 | // \\ }; | |
| 2044 | // \\ | |
| 2045 | // \\ // at end | |
| 2046 | // \\}; | |
| 2047 | // \\ | |
| 2048 | // ); | |
| 2049 | //} | |
| 2050 | // | |
| 2051 | //test "zig fmt: array literal with 1 item on 1 line" { | |
| 2052 | // try testCanonical( | |
| 2053 | // \\var s = []const u64{0} ** 25; | |
| 2054 | // \\ | |
| 2055 | // ); | |
| 2056 | //} | |
| 2057 | // | |
| 2058 | //test "zig fmt: comments before global variables" { | |
| 2059 | // try testCanonical( | |
| 2060 | // \\/// Foo copies keys and values before they go into the map, and | |
| 2061 | // \\/// frees them when they get removed. | |
| 2062 | // \\pub const Foo = struct {}; | |
| 2063 | // \\ | |
| 2064 | // ); | |
| 2065 | //} | |
| 2066 | // | |
| 2067 | //test "zig fmt: comments in statements" { | |
| 2068 | // try testCanonical( | |
| 2069 | // \\test "std" { | |
| 2070 | // \\ // statement comment | |
| 2071 | // \\ _ = @import("foo/bar.zig"); | |
| 2072 | // \\ | |
| 2073 | // \\ // middle | |
| 2074 | // \\ // middle2 | |
| 2075 | // \\ | |
| 2076 | // \\ // end | |
| 2077 | // \\} | |
| 2078 | // \\ | |
| 2079 | // ); | |
| 2080 | //} | |
| 2081 | // | |
| 2082 | //test "zig fmt: comments before test decl" { | |
| 2083 | // try testCanonical( | |
| 2084 | // \\/// top level doc comment | |
| 2085 | // \\test "hi" {} | |
| 2086 | // \\ | |
| 2087 | // \\// top level normal comment | |
| 2088 | // \\test "hi" {} | |
| 2089 | // \\ | |
| 2090 | // \\// middle | |
| 2091 | // \\ | |
| 2092 | // \\// end | |
| 2093 | // \\ | |
| 2094 | // ); | |
| 2095 | //} | |
| 2096 | // | |
| 2097 | //test "zig fmt: preserve spacing" { | |
| 2098 | // try testCanonical( | |
| 2099 | // \\const std = @import("std"); | |
| 2100 | // \\ | |
| 2101 | // \\pub fn main() !void { | |
| 2102 | // \\ var stdout_file = std.io.getStdOut; | |
| 2103 | // \\ var stdout_file = std.io.getStdOut; | |
| 2104 | // \\ | |
| 2105 | // \\ var stdout_file = std.io.getStdOut; | |
| 2106 | // \\ var stdout_file = std.io.getStdOut; | |
| 2107 | // \\} | |
| 2108 | // \\ | |
| 2109 | // ); | |
| 2110 | //} | |
| 2111 | // | |
| 2112 | //test "zig fmt: return types" { | |
| 2113 | // try testCanonical( | |
| 2114 | // \\pub fn main() !void {} | |
| 2115 | // \\pub fn main() anytype {} | |
| 2116 | // \\pub fn main() i32 {} | |
| 2117 | // \\ | |
| 2118 | // ); | |
| 2119 | //} | |
| 2120 | // | |
| 2121 | //test "zig fmt: imports" { | |
| 2122 | // try testCanonical( | |
| 2123 | // \\const std = @import("std"); | |
| 2124 | // \\const std = @import(); | |
| 2125 | // \\ | |
| 2126 | // ); | |
| 2127 | //} | |
| 2128 | // | |
| 2129 | //test "zig fmt: global declarations" { | |
| 2130 | // try testCanonical( | |
| 2131 | // \\const a = b; | |
| 2132 | // \\pub const a = b; | |
| 2133 | // \\var a = b; | |
| 2134 | // \\pub var a = b; | |
| 2135 | // \\const a: i32 = b; | |
| 2136 | // \\pub const a: i32 = b; | |
| 2137 | // \\var a: i32 = b; | |
| 2138 | // \\pub var a: i32 = b; | |
| 2139 | // \\extern const a: i32 = b; | |
| 2140 | // \\pub extern const a: i32 = b; | |
| 2141 | // \\extern var a: i32 = b; | |
| 2142 | // \\pub extern var a: i32 = b; | |
| 2143 | // \\extern "a" const a: i32 = b; | |
| 2144 | // \\pub extern "a" const a: i32 = b; | |
| 2145 | // \\extern "a" var a: i32 = b; | |
| 2146 | // \\pub extern "a" var a: i32 = b; | |
| 2147 | // \\ | |
| 2148 | // ); | |
| 2149 | //} | |
| 2150 | // | |
| 2151 | //test "zig fmt: extern declaration" { | |
| 2152 | // try testCanonical( | |
| 2153 | // \\extern var foo: c_int; | |
| 2154 | // \\ | |
| 2155 | // ); | |
| 2156 | //} | |
| 2157 | // | |
| 2158 | //test "zig fmt: alignment" { | |
| 2159 | // try testCanonical( | |
| 2160 | // \\var foo: c_int align(1); | |
| 2161 | // \\ | |
| 2162 | // ); | |
| 2163 | //} | |
| 2164 | // | |
| 2165 | //test "zig fmt: C main" { | |
| 2166 | // try testCanonical( | |
| 2167 | // \\fn main(argc: c_int, argv: **u8) c_int { | |
| 2168 | // \\ const a = b; | |
| 2169 | // \\} | |
| 2170 | // \\ | |
| 2171 | // ); | |
| 2172 | //} | |
| 2173 | // | |
| 2174 | //test "zig fmt: return" { | |
| 2175 | // try testCanonical( | |
| 2176 | // \\fn foo(argc: c_int, argv: **u8) c_int { | |
| 2177 | // \\ return 0; | |
| 2178 | // \\} | |
| 2179 | // \\ | |
| 2180 | // \\fn bar() void { | |
| 2181 | // \\ return; | |
| 2182 | // \\} | |
| 2183 | // \\ | |
| 2184 | // ); | |
| 2185 | //} | |
| 2186 | // | |
| 2187 | //test "zig fmt: pointer attributes" { | |
| 2188 | // try testCanonical( | |
| 2189 | // \\extern fn f1(s: *align(*u8) u8) c_int; | |
| 2190 | // \\extern fn f2(s: **align(1) *const *volatile u8) c_int; | |
| 2191 | // \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; | |
| 2192 | // \\extern fn f4(s: *align(1) const volatile u8) c_int; | |
| 2193 | // \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; | |
| 2194 | // \\ | |
| 2195 | // ); | |
| 2196 | //} | |
| 2197 | // | |
| 2198 | //test "zig fmt: slice attributes" { | |
| 2199 | // try testCanonical( | |
| 2200 | // \\extern fn f1(s: *align(*u8) u8) c_int; | |
| 2201 | // \\extern fn f2(s: **align(1) *const *volatile u8) c_int; | |
| 2202 | // \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; | |
| 2203 | // \\extern fn f4(s: *align(1) const volatile u8) c_int; | |
| 2204 | // \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; | |
| 2205 | // \\ | |
| 2206 | // ); | |
| 2207 | //} | |
| 2208 | // | |
| 2209 | //test "zig fmt: test declaration" { | |
| 2210 | // try testCanonical( | |
| 2211 | // \\test "test name" { | |
| 2212 | // \\ const a = 1; | |
| 2213 | // \\ var b = 1; | |
| 2214 | // \\} | |
| 2215 | // \\ | |
| 2216 | // ); | |
| 2217 | //} | |
| 2218 | // | |
| 2219 | //test "zig fmt: infix operators" { | |
| 2220 | // try testCanonical( | |
| 2221 | // \\test "infix operators" { | |
| 2222 | // \\ var i = undefined; | |
| 2223 | // \\ i = 2; | |
| 2224 | // \\ i *= 2; | |
| 2225 | // \\ i |= 2; | |
| 2226 | // \\ i ^= 2; | |
| 2227 | // \\ i <<= 2; | |
| 2228 | // \\ i >>= 2; | |
| 2229 | // \\ i &= 2; | |
| 2230 | // \\ i *= 2; | |
| 2231 | // \\ i *%= 2; | |
| 2232 | // \\ i -= 2; | |
| 2233 | // \\ i -%= 2; | |
| 2234 | // \\ i += 2; | |
| 2235 | // \\ i +%= 2; | |
| 2236 | // \\ i /= 2; | |
| 2237 | // \\ i %= 2; | |
| 2238 | // \\ _ = i == i; | |
| 2239 | // \\ _ = i != i; | |
| 2240 | // \\ _ = i != i; | |
| 2241 | // \\ _ = i.i; | |
| 2242 | // \\ _ = i || i; | |
| 2243 | // \\ _ = i!i; | |
| 2244 | // \\ _ = i ** i; | |
| 2245 | // \\ _ = i ++ i; | |
| 2246 | // \\ _ = i orelse i; | |
| 2247 | // \\ _ = i % i; | |
| 2248 | // \\ _ = i / i; | |
| 2249 | // \\ _ = i *% i; | |
| 2250 | // \\ _ = i * i; | |
| 2251 | // \\ _ = i -% i; | |
| 2252 | // \\ _ = i - i; | |
| 2253 | // \\ _ = i +% i; | |
| 2254 | // \\ _ = i + i; | |
| 2255 | // \\ _ = i << i; | |
| 2256 | // \\ _ = i >> i; | |
| 2257 | // \\ _ = i & i; | |
| 2258 | // \\ _ = i ^ i; | |
| 2259 | // \\ _ = i | i; | |
| 2260 | // \\ _ = i >= i; | |
| 2261 | // \\ _ = i <= i; | |
| 2262 | // \\ _ = i > i; | |
| 2263 | // \\ _ = i < i; | |
| 2264 | // \\ _ = i and i; | |
| 2265 | // \\ _ = i or i; | |
| 2266 | // \\} | |
| 2267 | // \\ | |
| 2268 | // ); | |
| 2269 | //} | |
| 2270 | // | |
| 2271 | //test "zig fmt: precedence" { | |
| 2272 | // try testCanonical( | |
| 2273 | // \\test "precedence" { | |
| 2274 | // \\ a!b(); | |
| 2275 | // \\ (a!b)(); | |
| 2276 | // \\ !a!b; | |
| 2277 | // \\ !(a!b); | |
| 2278 | // \\ !a{}; | |
| 2279 | // \\ !(a{}); | |
| 2280 | // \\ a + b{}; | |
| 2281 | // \\ (a + b){}; | |
| 2282 | // \\ a << b + c; | |
| 2283 | // \\ (a << b) + c; | |
| 2284 | // \\ a & b << c; | |
| 2285 | // \\ (a & b) << c; | |
| 2286 | // \\ a ^ b & c; | |
| 2287 | // \\ (a ^ b) & c; | |
| 2288 | // \\ a | b ^ c; | |
| 2289 | // \\ (a | b) ^ c; | |
| 2290 | // \\ a == b | c; | |
| 2291 | // \\ (a == b) | c; | |
| 2292 | // \\ a and b == c; | |
| 2293 | // \\ (a and b) == c; | |
| 2294 | // \\ a or b and c; | |
| 2295 | // \\ (a or b) and c; | |
| 2296 | // \\ (a or b) and c; | |
| 2297 | // \\} | |
| 2298 | // \\ | |
| 2299 | // ); | |
| 2300 | //} | |
| 2301 | // | |
| 2302 | //test "zig fmt: prefix operators" { | |
| 2303 | // try testCanonical( | |
| 2304 | // \\test "prefix operators" { | |
| 2305 | // \\ try return --%~!&0; | |
| 2306 | // \\} | |
| 2307 | // \\ | |
| 2308 | // ); | |
| 2309 | //} | |
| 2310 | // | |
| 2311 | //test "zig fmt: call expression" { | |
| 2312 | // try testCanonical( | |
| 2313 | // \\test "test calls" { | |
| 2314 | // \\ a(); | |
| 2315 | // \\ a(1); | |
| 2316 | // \\ a(1, 2); | |
| 2317 | // \\ a(1, 2) + a(1, 2); | |
| 2318 | // \\} | |
| 2319 | // \\ | |
| 2320 | // ); | |
| 2321 | //} | |
| 2322 | // | |
| 2323 | //test "zig fmt: anytype type" { | |
| 2324 | // try testCanonical( | |
| 2325 | // \\fn print(args: anytype) anytype {} | |
| 2326 | // \\ | |
| 2327 | // ); | |
| 2328 | //} | |
| 2329 | // | |
| 2330 | //test "zig fmt: functions" { | |
| 2331 | // try testCanonical( | |
| 2332 | // \\extern fn puts(s: *const u8) c_int; | |
| 2333 | // \\extern "c" fn puts(s: *const u8) c_int; | |
| 2334 | // \\export fn puts(s: *const u8) c_int; | |
| 2335 | // \\inline fn puts(s: *const u8) c_int; | |
| 2336 | // \\noinline fn puts(s: *const u8) c_int; | |
| 2337 | // \\pub extern fn puts(s: *const u8) c_int; | |
| 2338 | // \\pub extern "c" fn puts(s: *const u8) c_int; | |
| 2339 | // \\pub export fn puts(s: *const u8) c_int; | |
| 2340 | // \\pub inline fn puts(s: *const u8) c_int; | |
| 2341 | // \\pub noinline fn puts(s: *const u8) c_int; | |
| 2342 | // \\pub extern fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2343 | // \\pub extern "c" fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2344 | // \\pub export fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2345 | // \\pub inline fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2346 | // \\pub noinline fn puts(s: *const u8) align(2 + 2) c_int; | |
| 2347 | // \\ | |
| 2348 | // ); | |
| 2349 | //} | |
| 2350 | // | |
| 2351 | //test "zig fmt: multiline string" { | |
| 2352 | // try testCanonical( | |
| 2353 | // \\test "" { | |
| 2354 | // \\ const s1 = | |
| 2355 | // \\ \\one | |
| 2356 | // \\ \\two) | |
| 2357 | // \\ \\three | |
| 2358 | // \\ ; | |
| 2359 | // \\ const s3 = // hi | |
| 2360 | // \\ \\one | |
| 2361 | // \\ \\two) | |
| 2362 | // \\ \\three | |
| 2363 | // \\ ; | |
| 2364 | // \\} | |
| 2365 | // \\ | |
| 2366 | // ); | |
| 2367 | //} | |
| 2368 | // | |
| 2369 | //test "zig fmt: values" { | |
| 2370 | // try testCanonical( | |
| 2371 | // \\test "values" { | |
| 2372 | // \\ 1; | |
| 2373 | // \\ 1.0; | |
| 2374 | // \\ "string"; | |
| 2375 | // \\ 'c'; | |
| 2376 | // \\ true; | |
| 2377 | // \\ false; | |
| 2378 | // \\ null; | |
| 2379 | // \\ undefined; | |
| 2380 | // \\ anyerror; | |
| 2381 | // \\ this; | |
| 2382 | // \\ unreachable; | |
| 2383 | // \\} | |
| 2384 | // \\ | |
| 2385 | // ); | |
| 2386 | //} | |
| 2387 | // | |
| 2388 | //test "zig fmt: indexing" { | |
| 2389 | // try testCanonical( | |
| 2390 | // \\test "test index" { | |
| 2391 | // \\ a[0]; | |
| 2392 | // \\ a[0 + 5]; | |
| 2393 | // \\ a[0..]; | |
| 2394 | // \\ a[0..5]; | |
| 2395 | // \\ a[a[0]]; | |
| 2396 | // \\ a[a[0..]]; | |
| 2397 | // \\ a[a[0..5]]; | |
| 2398 | // \\ a[a[0]..]; | |
| 2399 | // \\ a[a[0..5]..]; | |
| 2400 | // \\ a[a[0]..a[0]]; | |
| 2401 | // \\ a[a[0..5]..a[0]]; | |
| 2402 | // \\ a[a[0..5]..a[0..5]]; | |
| 2403 | // \\} | |
| 2404 | // \\ | |
| 2405 | // ); | |
| 2406 | //} | |
| 2407 | // | |
| 2408 | //test "zig fmt: struct declaration" { | |
| 2409 | // try testCanonical( | |
| 2410 | // \\const S = struct { | |
| 2411 | // \\ const Self = @This(); | |
| 2412 | // \\ f1: u8, | |
| 2413 | // \\ f3: u8, | |
| 2414 | // \\ | |
| 2415 | // \\ f2: u8, | |
| 2416 | // \\ | |
| 2417 | // \\ fn method(self: *Self) Self { | |
| 2418 | // \\ return self.*; | |
| 2419 | // \\ } | |
| 2420 | // \\}; | |
| 2421 | // \\ | |
| 2422 | // \\const Ps = packed struct { | |
| 2423 | // \\ a: u8, | |
| 2424 | // \\ b: u8, | |
| 2425 | // \\ | |
| 2426 | // \\ c: u8, | |
| 2427 | // \\}; | |
| 2428 | // \\ | |
| 2429 | // \\const Es = extern struct { | |
| 2430 | // \\ a: u8, | |
| 2431 | // \\ b: u8, | |
| 2432 | // \\ | |
| 2433 | // \\ c: u8, | |
| 2434 | // \\}; | |
| 2435 | // \\ | |
| 2436 | // ); | |
| 2437 | //} | |
| 2438 | // | |
| 2439 | //test "zig fmt: enum declaration" { | |
| 2440 | // try testCanonical( | |
| 2441 | // \\const E = enum { | |
| 2442 | // \\ Ok, | |
| 2443 | // \\ SomethingElse = 0, | |
| 2444 | // \\}; | |
| 2445 | // \\ | |
| 2446 | // \\const E2 = enum(u8) { | |
| 2447 | // \\ Ok, | |
| 2448 | // \\ SomethingElse = 255, | |
| 2449 | // \\ SomethingThird, | |
| 2450 | // \\}; | |
| 2451 | // \\ | |
| 2452 | // \\const Ee = extern enum { | |
| 2453 | // \\ Ok, | |
| 2454 | // \\ SomethingElse, | |
| 2455 | // \\ SomethingThird, | |
| 2456 | // \\}; | |
| 2457 | // \\ | |
| 2458 | // \\const Ep = packed enum { | |
| 2459 | // \\ Ok, | |
| 2460 | // \\ SomethingElse, | |
| 2461 | // \\ SomethingThird, | |
| 2462 | // \\}; | |
| 2463 | // \\ | |
| 2464 | // ); | |
| 2465 | //} | |
| 2466 | // | |
| 2467 | //test "zig fmt: union declaration" { | |
| 2468 | // try testCanonical( | |
| 2469 | // \\const U = union { | |
| 2470 | // \\ Int: u8, | |
| 2471 | // \\ Float: f32, | |
| 2472 | // \\ None, | |
| 2473 | // \\ Bool: bool, | |
| 2474 | // \\}; | |
| 2475 | // \\ | |
| 2476 | // \\const Ue = union(enum) { | |
| 2477 | // \\ Int: u8, | |
| 2478 | // \\ Float: f32, | |
| 2479 | // \\ None, | |
| 2480 | // \\ Bool: bool, | |
| 2481 | // \\}; | |
| 2482 | // \\ | |
| 2483 | // \\const E = enum { | |
| 2484 | // \\ Int, | |
| 2485 | // \\ Float, | |
| 2486 | // \\ None, | |
| 2487 | // \\ Bool, | |
| 2488 | // \\}; | |
| 2489 | // \\ | |
| 2490 | // \\const Ue2 = union(E) { | |
| 2491 | // \\ Int: u8, | |
| 2492 | // \\ Float: f32, | |
| 2493 | // \\ None, | |
| 2494 | // \\ Bool: bool, | |
| 2495 | // \\}; | |
| 2496 | // \\ | |
| 2497 | // \\const Eu = extern union { | |
| 2498 | // \\ Int: u8, | |
| 2499 | // \\ Float: f32, | |
| 2500 | // \\ None, | |
| 2501 | // \\ Bool: bool, | |
| 2502 | // \\}; | |
| 2503 | // \\ | |
| 2504 | // ); | |
| 2505 | //} | |
| 2506 | // | |
| 2507 | //test "zig fmt: arrays" { | |
| 2508 | // try testCanonical( | |
| 2509 | // \\test "test array" { | |
| 2510 | // \\ const a: [2]u8 = [2]u8{ | |
| 2511 | // \\ 1, | |
| 2512 | // \\ 2, | |
| 2513 | // \\ }; | |
| 2514 | // \\ const a: [2]u8 = []u8{ | |
| 2515 | // \\ 1, | |
| 2516 | // \\ 2, | |
| 2517 | // \\ }; | |
| 2518 | // \\ const a: [0]u8 = []u8{}; | |
| 2519 | // \\ const x: [4:0]u8 = undefined; | |
| 2520 | // \\} | |
| 2521 | // \\ | |
| 2522 | // ); | |
| 2523 | //} | |
| 2524 | // | |
| 2525 | //test "zig fmt: container initializers" { | |
| 2526 | // try testCanonical( | |
| 2527 | // \\const a0 = []u8{}; | |
| 2528 | // \\const a1 = []u8{1}; | |
| 2529 | // \\const a2 = []u8{ | |
| 2530 | // \\ 1, | |
| 2531 | // \\ 2, | |
| 2532 | // \\ 3, | |
| 2533 | // \\ 4, | |
| 2534 | // \\}; | |
| 2535 | // \\const s0 = S{}; | |
| 2536 | // \\const s1 = S{ .a = 1 }; | |
| 2537 | // \\const s2 = S{ | |
| 2538 | // \\ .a = 1, | |
| 2539 | // \\ .b = 2, | |
| 2540 | // \\}; | |
| 2541 | // \\ | |
| 2542 | // ); | |
| 2543 | //} | |
| 2544 | // | |
| 2545 | //test "zig fmt: catch" { | |
| 2546 | // try testCanonical( | |
| 2547 | // \\test "catch" { | |
| 2548 | // \\ const a: anyerror!u8 = 0; | |
| 2549 | // \\ _ = a catch return; | |
| 2550 | // \\ _ = a catch |err| return; | |
| 2551 | // \\} | |
| 2552 | // \\ | |
| 2553 | // ); | |
| 2554 | //} | |
| 2555 | // | |
| 2556 | //test "zig fmt: blocks" { | |
| 2557 | // try testCanonical( | |
| 2558 | // \\test "blocks" { | |
| 2559 | // \\ { | |
| 2560 | // \\ const a = 0; | |
| 2561 | // \\ const b = 0; | |
| 2562 | // \\ } | |
| 2563 | // \\ | |
| 2564 | // \\ blk: { | |
| 2565 | // \\ const a = 0; | |
| 2566 | // \\ const b = 0; | |
| 2567 | // \\ } | |
| 2568 | // \\ | |
| 2569 | // \\ const r = blk: { | |
| 2570 | // \\ const a = 0; | |
| 2571 | // \\ const b = 0; | |
| 2572 | // \\ }; | |
| 2573 | // \\} | |
| 2574 | // \\ | |
| 2575 | // ); | |
| 2576 | //} | |
| 2577 | // | |
| 2578 | //test "zig fmt: switch" { | |
| 2579 | // try testCanonical( | |
| 2580 | // \\test "switch" { | |
| 2581 | // \\ switch (0) { | |
| 2582 | // \\ 0 => {}, | |
| 2583 | // \\ 1 => unreachable, | |
| 2584 | // \\ 2, 3 => {}, | |
| 2585 | // \\ 4...7 => {}, | |
| 2586 | // \\ 1 + 4 * 3 + 22 => {}, | |
| 2587 | // \\ else => { | |
| 2588 | // \\ const a = 1; | |
| 2589 | // \\ const b = a; | |
| 2590 | // \\ }, | |
| 2591 | // \\ } | |
| 2592 | // \\ | |
| 2593 | // \\ const res = switch (0) { | |
| 2594 | // \\ 0 => 0, | |
| 2595 | // \\ 1 => 2, | |
| 2596 | // \\ 1 => a = 4, | |
| 2597 | // \\ else => 4, | |
| 2598 | // \\ }; | |
| 2599 | // \\ | |
| 2600 | // \\ const Union = union(enum) { | |
| 2601 | // \\ Int: i64, | |
| 2602 | // \\ Float: f64, | |
| 2603 | // \\ }; | |
| 2604 | // \\ | |
| 2605 | // \\ switch (u) { | |
| 2606 | // \\ Union.Int => |int| {}, | |
| 2607 | // \\ Union.Float => |*float| unreachable, | |
| 2608 | // \\ } | |
| 2609 | // \\} | |
| 2610 | // \\ | |
| 2611 | // ); | |
| 2612 | //} | |
| 2613 | // | |
| 2614 | //test "zig fmt: while" { | |
| 2615 | // try testCanonical( | |
| 2616 | // \\test "while" { | |
| 2617 | // \\ while (10 < 1) unreachable; | |
| 2618 | // \\ | |
| 2619 | // \\ while (10 < 1) unreachable else unreachable; | |
| 2620 | // \\ | |
| 2621 | // \\ while (10 < 1) { | |
| 2622 | // \\ unreachable; | |
| 2623 | // \\ } | |
| 2624 | // \\ | |
| 2625 | // \\ while (10 < 1) | |
| 2626 | // \\ unreachable; | |
| 2627 | // \\ | |
| 2628 | // \\ var i: usize = 0; | |
| 2629 | // \\ while (i < 10) : (i += 1) { | |
| 2630 | // \\ continue; | |
| 2631 | // \\ } | |
| 2632 | // \\ | |
| 2633 | // \\ i = 0; | |
| 2634 | // \\ while (i < 10) : (i += 1) | |
| 2635 | // \\ continue; | |
| 2636 | // \\ | |
| 2637 | // \\ i = 0; | |
| 2638 | // \\ var j: usize = 0; | |
| 2639 | // \\ while (i < 10) : ({ | |
| 2640 | // \\ i += 1; | |
| 2641 | // \\ j += 1; | |
| 2642 | // \\ }) { | |
| 2643 | // \\ continue; | |
| 2644 | // \\ } | |
| 2645 | // \\ | |
| 2646 | // \\ var a: ?u8 = 2; | |
| 2647 | // \\ while (a) |v| : (a = null) { | |
| 2648 | // \\ continue; | |
| 2649 | // \\ } | |
| 2650 | // \\ | |
| 2651 | // \\ while (a) |v| : (a = null) | |
| 2652 | // \\ unreachable; | |
| 2653 | // \\ | |
| 2654 | // \\ label: while (10 < 0) { | |
| 2655 | // \\ unreachable; | |
| 2656 | // \\ } | |
| 2657 | // \\ | |
| 2658 | // \\ const res = while (0 < 10) { | |
| 2659 | // \\ break 7; | |
| 2660 | // \\ } else { | |
| 2661 | // \\ unreachable; | |
| 2662 | // \\ }; | |
| 2663 | // \\ | |
| 2664 | // \\ const res = while (0 < 10) | |
| 2665 | // \\ break 7 | |
| 2666 | // \\ else | |
| 2667 | // \\ unreachable; | |
| 2668 | // \\ | |
| 2669 | // \\ var a: anyerror!u8 = 0; | |
| 2670 | // \\ while (a) |v| { | |
| 2671 | // \\ a = error.Err; | |
| 2672 | // \\ } else |err| { | |
| 2673 | // \\ i = 1; | |
| 2674 | // \\ } | |
| 2675 | // \\ | |
| 2676 | // \\ comptime var k: usize = 0; | |
| 2677 | // \\ inline while (i < 10) : (i += 1) | |
| 2678 | // \\ j += 2; | |
| 2679 | // \\} | |
| 2680 | // \\ | |
| 2681 | // ); | |
| 2682 | //} | |
| 2683 | // | |
| 2684 | //test "zig fmt: for" { | |
| 2685 | // try testCanonical( | |
| 2686 | // \\test "for" { | |
| 2687 | // \\ for (a) |v| { | |
| 2688 | // \\ continue; | |
| 2689 | // \\ } | |
| 2690 | // \\ | |
| 2691 | // \\ for (a) |v| continue; | |
| 2692 | // \\ | |
| 2693 | // \\ for (a) |v| continue else return; | |
| 2694 | // \\ | |
| 2695 | // \\ for (a) |v| { | |
| 2696 | // \\ continue; | |
| 2697 | // \\ } else return; | |
| 2698 | // \\ | |
| 2699 | // \\ for (a) |v| continue else { | |
| 2700 | // \\ return; | |
| 2701 | // \\ } | |
| 2702 | // \\ | |
| 2703 | // \\ for (a) |v| | |
| 2704 | // \\ continue | |
| 2705 | // \\ else | |
| 2706 | // \\ return; | |
| 2707 | // \\ | |
| 2708 | // \\ for (a) |v| | |
| 2709 | // \\ continue; | |
| 2710 | // \\ | |
| 2711 | // \\ for (a) |*v| | |
| 2712 | // \\ continue; | |
| 2713 | // \\ | |
| 2714 | // \\ for (a) |v, i| { | |
| 2715 | // \\ continue; | |
| 2716 | // \\ } | |
| 2717 | // \\ | |
| 2718 | // \\ for (a) |v, i| | |
| 2719 | // \\ continue; | |
| 2720 | // \\ | |
| 2721 | // \\ for (a) |b| switch (b) { | |
| 2722 | // \\ c => {}, | |
| 2723 | // \\ d => {}, | |
| 2724 | // \\ }; | |
| 2725 | // \\ | |
| 2726 | // \\ for (a) |b| | |
| 2727 | // \\ switch (b) { | |
| 2728 | // \\ c => {}, | |
| 2729 | // \\ d => {}, | |
| 2730 | // \\ }; | |
| 2731 | // \\ | |
| 2732 | // \\ const res = for (a) |v, i| { | |
| 2733 | // \\ break v; | |
| 2734 | // \\ } else { | |
| 2735 | // \\ unreachable; | |
| 2736 | // \\ }; | |
| 2737 | // \\ | |
| 2738 | // \\ var num: usize = 0; | |
| 2739 | // \\ inline for (a) |v, i| { | |
| 2740 | // \\ num += v; | |
| 2741 | // \\ num += i; | |
| 2742 | // \\ } | |
| 2743 | // \\} | |
| 2744 | // \\ | |
| 2745 | // ); | |
| 2746 | // | |
| 2747 | // try testTransform( | |
| 2748 | // \\test "fix for" { | |
| 2749 | // \\ for (a) |x| | |
| 2750 | // \\ f(x) else continue; | |
| 2751 | // \\} | |
| 2752 | // \\ | |
| 2753 | // , | |
| 2754 | // \\test "fix for" { | |
| 2755 | // \\ for (a) |x| | |
| 2756 | // \\ f(x) | |
| 2757 | // \\ else continue; | |
| 2758 | // \\} | |
| 2759 | // \\ | |
| 2760 | // ); | |
| 2761 | //} | |
| 2762 | // | |
| 2763 | //test "zig fmt: if" { | |
| 2764 | // try testCanonical( | |
| 2765 | // \\test "if" { | |
| 2766 | // \\ if (10 < 0) { | |
| 2767 | // \\ unreachable; | |
| 2768 | // \\ } | |
| 2769 | // \\ | |
| 2770 | // \\ if (10 < 0) unreachable; | |
| 2771 | // \\ | |
| 2772 | // \\ if (10 < 0) { | |
| 2773 | // \\ unreachable; | |
| 2774 | // \\ } else { | |
| 2775 | // \\ const a = 20; | |
| 2776 | // \\ } | |
| 2777 | // \\ | |
| 2778 | // \\ if (10 < 0) { | |
| 2779 | // \\ unreachable; | |
| 2780 | // \\ } else if (5 < 0) { | |
| 2781 | // \\ unreachable; | |
| 2782 | // \\ } else { | |
| 2783 | // \\ const a = 20; | |
| 2784 | // \\ } | |
| 2785 | // \\ | |
| 2786 | // \\ const is_world_broken = if (10 < 0) true else false; | |
| 2787 | // \\ const some_number = 1 + if (10 < 0) 2 else 3; | |
| 2788 | // \\ | |
| 2789 | // \\ const a: ?u8 = 10; | |
| 2790 | // \\ const b: ?u8 = null; | |
| 2791 | // \\ if (a) |v| { | |
| 2792 | // \\ const some = v; | |
| 2793 | // \\ } else if (b) |*v| { | |
| 2794 | // \\ unreachable; | |
| 2795 | // \\ } else { | |
| 2796 | // \\ const some = 10; | |
| 2797 | // \\ } | |
| 2798 | // \\ | |
| 2799 | // \\ const non_null_a = if (a) |v| v else 0; | |
| 2800 | // \\ | |
| 2801 | // \\ const a_err: anyerror!u8 = 0; | |
| 2802 | // \\ if (a_err) |v| { | |
| 2803 | // \\ const p = v; | |
| 2804 | // \\ } else |err| { | |
| 2805 | // \\ unreachable; | |
| 2806 | // \\ } | |
| 2807 | // \\} | |
| 2808 | // \\ | |
| 2809 | // ); | |
| 2810 | //} | |
| 2811 | // | |
| 2812 | //test "zig fmt: defer" { | |
| 2813 | // try testCanonical( | |
| 2814 | // \\test "defer" { | |
| 2815 | // \\ var i: usize = 0; | |
| 2816 | // \\ defer i = 1; | |
| 2817 | // \\ defer { | |
| 2818 | // \\ i += 2; | |
| 2819 | // \\ i *= i; | |
| 2820 | // \\ } | |
| 2821 | // \\ | |
| 2822 | // \\ errdefer i += 3; | |
| 2823 | // \\ errdefer { | |
| 2824 | // \\ i += 2; | |
| 2825 | // \\ i /= i; | |
| 2826 | // \\ } | |
| 2827 | // \\} | |
| 2828 | // \\ | |
| 2829 | // ); | |
| 2830 | //} | |
| 2831 | // | |
| 2832 | //test "zig fmt: comptime" { | |
| 2833 | // try testCanonical( | |
| 2834 | // \\fn a() u8 { | |
| 2835 | // \\ return 5; | |
| 2836 | // \\} | |
| 2837 | // \\ | |
| 2838 | // \\fn b(comptime i: u8) u8 { | |
| 2839 | // \\ return i; | |
| 2840 | // \\} | |
| 2841 | // \\ | |
| 2842 | // \\const av = comptime a(); | |
| 2843 | // \\const av2 = comptime blk: { | |
| 2844 | // \\ var res = a(); | |
| 2845 | // \\ res *= b(2); | |
| 2846 | // \\ break :blk res; | |
| 2847 | // \\}; | |
| 2848 | // \\ | |
| 2849 | // \\comptime { | |
| 2850 | // \\ _ = a(); | |
| 2851 | // \\} | |
| 2852 | // \\ | |
| 2853 | // \\test "comptime" { | |
| 2854 | // \\ const av3 = comptime a(); | |
| 2855 | // \\ const av4 = comptime blk: { | |
| 2856 | // \\ var res = a(); | |
| 2857 | // \\ res *= a(); | |
| 2858 | // \\ break :blk res; | |
| 2859 | // \\ }; | |
| 2860 | // \\ | |
| 2861 | // \\ comptime var i = 0; | |
| 2862 | // \\ comptime { | |
| 2863 | // \\ i = a(); | |
| 2864 | // \\ i += b(i); | |
| 2865 | // \\ } | |
| 2866 | // \\} | |
| 2867 | // \\ | |
| 2868 | // ); | |
| 2869 | //} | |
| 2870 | // | |
| 2871 | //test "zig fmt: fn type" { | |
| 2872 | // try testCanonical( | |
| 2873 | // \\fn a(i: u8) u8 { | |
| 2874 | // \\ return i + 1; | |
| 2875 | // \\} | |
| 2876 | // \\ | |
| 2877 | // \\const a: fn (u8) u8 = undefined; | |
| 2878 | // \\const b: fn (u8) callconv(.Naked) u8 = undefined; | |
| 2879 | // \\const ap: fn (u8) u8 = a; | |
| 2880 | // \\ | |
| 2881 | // ); | |
| 2882 | //} | |
| 2883 | // | |
| 2884 | //test "zig fmt: inline asm" { | |
| 2885 | // try testCanonical( | |
| 2886 | // \\pub fn syscall1(number: usize, arg1: usize) usize { | |
| 2887 | // \\ return asm volatile ("syscall" | |
| 2888 | // \\ : [ret] "={rax}" (-> usize) | |
| 2889 | // \\ : [number] "{rax}" (number), | |
| 2890 | // \\ [arg1] "{rdi}" (arg1) | |
| 2891 | // \\ : "rcx", "r11" | |
| 2892 | // \\ ); | |
| 2893 | // \\} | |
| 2894 | // \\ | |
| 2895 | // ); | |
| 2896 | //} | |
| 2897 | // | |
| 2898 | //test "zig fmt: async functions" { | |
| 2899 | // try testCanonical( | |
| 2900 | // \\fn simpleAsyncFn() void { | |
| 2901 | // \\ const a = async a.b(); | |
| 2902 | // \\ x += 1; | |
| 2903 | // \\ suspend; | |
| 2904 | // \\ x += 1; | |
| 2905 | // \\ suspend; | |
| 2906 | // \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable; | |
| 2907 | // \\ await p; | |
| 2908 | // \\} | |
| 2909 | // \\ | |
| 2910 | // \\test "suspend, resume, await" { | |
| 2911 | // \\ const p: anyframe = async testAsyncSeq(); | |
| 2912 | // \\ resume p; | |
| 2913 | // \\ await p; | |
| 2914 | // \\} | |
| 2915 | // \\ | |
| 2916 | // ); | |
| 2917 | //} | |
| 2918 | // | |
| 2919 | //test "zig fmt: nosuspend" { | |
| 2920 | // try testCanonical( | |
| 2921 | // \\const a = nosuspend foo(); | |
| 2922 | // \\ | |
| 2923 | // ); | |
| 2924 | //} | |
| 2925 | // | |
| 2926 | //test "zig fmt: Block after if" { | |
| 2927 | // try testCanonical( | |
| 2928 | // \\test "Block after if" { | |
| 2929 | // \\ if (true) { | |
| 2930 | // \\ const a = 0; | |
| 2931 | // \\ } | |
| 2932 | // \\ | |
| 2933 | // \\ { | |
| 2934 | // \\ const a = 0; | |
| 2935 | // \\ } | |
| 2936 | // \\} | |
| 2937 | // \\ | |
| 2938 | // ); | |
| 2939 | //} | |
| 2940 | // | |
| 2941 | //test "zig fmt: use" { | |
| 2942 | // try testCanonical( | |
| 2943 | // \\usingnamespace @import("std"); | |
| 2944 | // \\pub usingnamespace @import("std"); | |
| 2945 | // \\ | |
| 2946 | // ); | |
| 2947 | //} | |
| 2948 | // | |
| 2949 | //test "zig fmt: string identifier" { | |
| 2950 | // try testCanonical( | |
| 2951 | // \\const @"a b" = @"c d".@"e f"; | |
| 2952 | // \\fn @"g h"() void {} | |
| 2953 | // \\ | |
| 2954 | // ); | |
| 2955 | //} | |
| 2956 | // | |
| 2957 | //test "zig fmt: error return" { | |
| 2958 | // try testCanonical( | |
| 2959 | // \\fn err() anyerror { | |
| 2960 | // \\ call(); | |
| 2961 | // \\ return error.InvalidArgs; | |
| 2962 | // \\} | |
| 2963 | // \\ | |
| 2964 | // ); | |
| 2965 | //} | |
| 2966 | // | |
| 2967 | //test "zig fmt: comptime block in container" { | |
| 2968 | // try testCanonical( | |
| 2969 | // \\pub fn container() type { | |
| 2970 | // \\ return struct { | |
| 2971 | // \\ comptime { | |
| 2972 | // \\ if (false) { | |
| 2973 | // \\ unreachable; | |
| 2974 | // \\ } | |
| 2975 | // \\ } | |
| 2976 | // \\ }; | |
| 2977 | // \\} | |
| 2978 | // \\ | |
| 2979 | // ); | |
| 2980 | //} | |
| 2981 | // | |
| 2982 | //test "zig fmt: inline asm parameter alignment" { | |
| 2983 | // try testCanonical( | |
| 2984 | // \\pub fn main() void { | |
| 2985 | // \\ asm volatile ( | |
| 2986 | // \\ \\ foo | |
| 2987 | // \\ \\ bar | |
| 2988 | // \\ ); | |
| 2989 | // \\ asm volatile ( | |
| 2990 | // \\ \\ foo | |
| 2991 | // \\ \\ bar | |
| 2992 | // \\ : [_] "" (-> usize), | |
| 2993 | // \\ [_] "" (-> usize) | |
| 2994 | // \\ ); | |
| 2995 | // \\ asm volatile ( | |
| 2996 | // \\ \\ foo | |
| 2997 | // \\ \\ bar | |
| 2998 | // \\ : | |
| 2999 | // \\ : [_] "" (0), | |
| 3000 | // \\ [_] "" (0) | |
| 3001 | // \\ ); | |
| 3002 | // \\ asm volatile ( | |
| 3003 | // \\ \\ foo | |
| 3004 | // \\ \\ bar | |
| 3005 | // \\ : | |
| 3006 | // \\ : | |
| 3007 | // \\ : "", "" | |
| 3008 | // \\ ); | |
| 3009 | // \\ asm volatile ( | |
| 3010 | // \\ \\ foo | |
| 3011 | // \\ \\ bar | |
| 3012 | // \\ : [_] "" (-> usize), | |
| 3013 | // \\ [_] "" (-> usize) | |
| 3014 | // \\ : [_] "" (0), | |
| 3015 | // \\ [_] "" (0) | |
| 3016 | // \\ : "", "" | |
| 3017 | // \\ ); | |
| 3018 | // \\} | |
| 3019 | // \\ | |
| 3020 | // ); | |
| 3021 | //} | |
| 3022 | // | |
| 3023 | //test "zig fmt: multiline string in array" { | |
| 3024 | // try testCanonical( | |
| 3025 | // \\const Foo = [][]const u8{ | |
| 3026 | // \\ \\aaa | |
| 3027 | // \\ , | |
| 3028 | // \\ \\bbb | |
| 3029 | // \\}; | |
| 3030 | // \\ | |
| 3031 | // \\fn bar() void { | |
| 3032 | // \\ const Foo = [][]const u8{ | |
| 3033 | // \\ \\aaa | |
| 3034 | // \\ , | |
| 3035 | // \\ \\bbb | |
| 3036 | // \\ }; | |
| 3037 | // \\ const Bar = [][]const u8{ // comment here | |
| 3038 | // \\ \\aaa | |
| 3039 | // \\ \\ | |
| 3040 | // \\ , // and another comment can go here | |
| 3041 | // \\ \\bbb | |
| 3042 | // \\ }; | |
| 3043 | // \\} | |
| 3044 | // \\ | |
| 3045 | // ); | |
| 3046 | //} | |
| 3047 | // | |
| 3048 | //test "zig fmt: if type expr" { | |
| 3049 | // try testCanonical( | |
| 3050 | // \\const mycond = true; | |
| 3051 | // \\pub fn foo() if (mycond) i32 else void { | |
| 3052 | // \\ if (mycond) { | |
| 3053 | // \\ return 42; | |
| 3054 | // \\ } | |
| 3055 | // \\} | |
| 3056 | // \\ | |
| 3057 | // ); | |
| 3058 | //} | |
| 3059 | //test "zig fmt: file ends with struct field" { | |
| 3060 | // try testCanonical( | |
| 3061 | // \\a: bool | |
| 3062 | // \\ | |
| 3063 | // ); | |
| 3064 | //} | |
| 3065 | // | |
| 3066 | //test "zig fmt: comment after empty comment" { | |
| 3067 | // try testTransform( | |
| 3068 | // \\const x = true; // | |
| 3069 | // \\// | |
| 3070 | // \\// | |
| 3071 | // \\//a | |
| 3072 | // \\ | |
| 3073 | // , | |
| 3074 | // \\const x = true; | |
| 3075 | // \\//a | |
| 3076 | // \\ | |
| 3077 | // ); | |
| 3078 | //} | |
| 3079 | // | |
| 3080 | //test "zig fmt: line comment in array" { | |
| 3081 | // try testTransform( | |
| 3082 | // \\test "a" { | |
| 3083 | // \\ var arr = [_]u32{ | |
| 3084 | // \\ 0 | |
| 3085 | // \\ // 1, | |
| 3086 | // \\ // 2, | |
| 3087 | // \\ }; | |
| 3088 | // \\} | |
| 3089 | // \\ | |
| 3090 | // , | |
| 3091 | // \\test "a" { | |
| 3092 | // \\ var arr = [_]u32{ | |
| 3093 | // \\ 0, // 1, | |
| 3094 | // \\ // 2, | |
| 3095 | // \\ }; | |
| 3096 | // \\} | |
| 3097 | // \\ | |
| 3098 | // ); | |
| 3099 | // try testCanonical( | |
| 3100 | // \\test "a" { | |
| 3101 | // \\ var arr = [_]u32{ | |
| 3102 | // \\ 0, | |
| 3103 | // \\ // 1, | |
| 3104 | // \\ // 2, | |
| 3105 | // \\ }; | |
| 3106 | // \\} | |
| 3107 | // \\ | |
| 3108 | // ); | |
| 3109 | //} | |
| 3110 | // | |
| 3111 | //test "zig fmt: comment after params" { | |
| 3112 | // try testTransform( | |
| 3113 | // \\fn a( | |
| 3114 | // \\ b: u32 | |
| 3115 | // \\ // c: u32, | |
| 3116 | // \\ // d: u32, | |
| 3117 | // \\) void {} | |
| 3118 | // \\ | |
| 3119 | // , | |
| 3120 | // \\fn a( | |
| 3121 | // \\ b: u32, // c: u32, | |
| 3122 | // \\ // d: u32, | |
| 3123 | // \\) void {} | |
| 3124 | // \\ | |
| 3125 | // ); | |
| 3126 | // try testCanonical( | |
| 3127 | // \\fn a( | |
| 3128 | // \\ b: u32, | |
| 3129 | // \\ // c: u32, | |
| 3130 | // \\ // d: u32, | |
| 3131 | // \\) void {} | |
| 3132 | // \\ | |
| 3133 | // ); | |
| 3134 | //} | |
| 3135 | // | |
| 3136 | //test "zig fmt: comment in array initializer/access" { | |
| 3137 | // try testCanonical( | |
| 3138 | // \\test "a" { | |
| 3139 | // \\ var a = x{ //aa | |
| 3140 | // \\ //bb | |
| 3141 | // \\ }; | |
| 3142 | // \\ var a = []x{ //aa | |
| 3143 | // \\ //bb | |
| 3144 | // \\ }; | |
| 3145 | // \\ var b = [ //aa | |
| 3146 | // \\ _ | |
| 3147 | // \\ ]x{ //aa | |
| 3148 | // \\ //bb | |
| 3149 | // \\ 9, | |
| 3150 | // \\ }; | |
| 3151 | // \\ var c = b[ //aa | |
| 3152 | // \\ 0 | |
| 3153 | // \\ ]; | |
| 3154 | // \\ var d = [_ | |
| 3155 | // \\ //aa | |
| 3156 | // \\ ]x{ //aa | |
| 3157 | // \\ //bb | |
| 3158 | // \\ 9, | |
| 3159 | // \\ }; | |
| 3160 | // \\ var e = d[0 | |
| 3161 | // \\ //aa | |
| 3162 | // \\ ]; | |
| 3163 | // \\} | |
| 3164 | // \\ | |
| 3165 | // ); | |
| 3166 | //} | |
| 3167 | // | |
| 3168 | //test "zig fmt: comments at several places in struct init" { | |
| 3169 | // try testTransform( | |
| 3170 | // \\var bar = Bar{ | |
| 3171 | // \\ .x = 10, // test | |
| 3172 | // \\ .y = "test" | |
| 3173 | // \\ // test | |
| 3174 | // \\}; | |
| 3175 | // \\ | |
| 3176 | // , | |
| 3177 | // \\var bar = Bar{ | |
| 3178 | // \\ .x = 10, // test | |
| 3179 | // \\ .y = "test", // test | |
| 3180 | // \\}; | |
| 3181 | // \\ | |
| 3182 | // ); | |
| 3183 | // | |
| 3184 | // try testCanonical( | |
| 3185 | // \\var bar = Bar{ // test | |
| 3186 | // \\ .x = 10, // test | |
| 3187 | // \\ .y = "test", | |
| 3188 | // \\ // test | |
| 3189 | // \\}; | |
| 3190 | // \\ | |
| 3191 | // ); | |
| 3192 | //} | |
| 3193 | // | |
| 3194 | //test "zig fmt: top level doc comments" { | |
| 3195 | // try testCanonical( | |
| 3196 | // \\//! tld 1 | |
| 3197 | // \\//! tld 2 | |
| 3198 | // \\//! tld 3 | |
| 3199 | // \\ | |
| 3200 | // \\// comment | |
| 3201 | // \\ | |
| 3202 | // \\/// A doc | |
| 3203 | // \\const A = struct { | |
| 3204 | // \\ //! A tld 1 | |
| 3205 | // \\ //! A tld 2 | |
| 3206 | // \\ //! A tld 3 | |
| 3207 | // \\}; | |
| 3208 | // \\ | |
| 3209 | // \\/// B doc | |
| 3210 | // \\const B = struct { | |
| 3211 | // \\ //! B tld 1 | |
| 3212 | // \\ //! B tld 2 | |
| 3213 | // \\ //! B tld 3 | |
| 3214 | // \\ | |
| 3215 | // \\ /// b doc | |
| 3216 | // \\ b: u32, | |
| 3217 | // \\}; | |
| 3218 | // \\ | |
| 3219 | // \\/// C doc | |
| 3220 | // \\const C = struct { | |
| 3221 | // \\ //! C tld 1 | |
| 3222 | // \\ //! C tld 2 | |
| 3223 | // \\ //! C tld 3 | |
| 3224 | // \\ | |
| 3225 | // \\ /// c1 doc | |
| 3226 | // \\ c1: u32, | |
| 3227 | // \\ | |
| 3228 | // \\ //! C tld 4 | |
| 3229 | // \\ //! C tld 5 | |
| 3230 | // \\ //! C tld 6 | |
| 3231 | // \\ | |
| 3232 | // \\ /// c2 doc | |
| 3233 | // \\ c2: u32, | |
| 3234 | // \\}; | |
| 3235 | // \\ | |
| 3236 | // ); | |
| 3237 | // try testCanonical( | |
| 3238 | // \\//! Top-level documentation. | |
| 3239 | // \\ | |
| 3240 | // \\/// This is A | |
| 3241 | // \\pub const A = usize; | |
| 3242 | // \\ | |
| 3243 | // ); | |
| 3244 | // try testCanonical( | |
| 3245 | // \\//! Nothing here | |
| 3246 | // \\ | |
| 3247 | // ); | |
| 3248 | //} | |
| 3249 | // | |
| 3250 | //test "zig fmt: extern without container keyword returns error" { | |
| 3251 | // try testError( | |
| 3252 | // \\const container = extern {}; | |
| 3253 | // \\ | |
| 3254 | // , &[_]Error{ | |
| 3255 | // .ExpectedExpr, | |
| 3256 | // .ExpectedVarDeclOrFn, | |
| 3257 | // }); | |
| 3258 | //} | |
| 3259 | // | |
| 3260 | //test "zig fmt: integer literals with underscore separators" { | |
| 3261 | // try testTransform( | |
| 3262 | // \\const | |
| 3263 | // \\ x = | |
| 3264 | // \\ 1_234_567 | |
| 3265 | // \\ +(0b0_1-0o7_0+0xff_FF ) + 0_0; | |
| 3266 | // , | |
| 3267 | // \\const x = | |
| 3268 | // \\ 1_234_567 + (0b0_1 - 0o7_0 + 0xff_FF) + 0_0; | |
| 3269 | // \\ | |
| 3270 | // ); | |
| 3271 | //} | |
| 3272 | // | |
| 3273 | //test "zig fmt: hex literals with underscore separators" { | |
| 3274 | // try testTransform( | |
| 3275 | // \\pub fn orMask(a: [ 1_000 ]u64, b: [ 1_000] u64) [1_000]u64 { | |
| 3276 | // \\ var c: [1_000]u64 = [1]u64{ 0xFFFF_FFFF_FFFF_FFFF}**1_000; | |
| 3277 | // \\ for (c [ 0_0 .. ]) |_, i| { | |
| 3278 | // \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA; | |
| 3279 | // \\ } | |
| 3280 | // \\ return c; | |
| 3281 | // \\} | |
| 3282 | // \\ | |
| 3283 | // \\ | |
| 3284 | // , | |
| 3285 | // \\pub fn orMask(a: [1_000]u64, b: [1_000]u64) [1_000]u64 { | |
| 3286 | // \\ var c: [1_000]u64 = [1]u64{0xFFFF_FFFF_FFFF_FFFF} ** 1_000; | |
| 3287 | // \\ for (c[0_0..]) |_, i| { | |
| 3288 | // \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA; | |
| 3289 | // \\ } | |
| 3290 | // \\ return c; | |
| 3291 | // \\} | |
| 3292 | // \\ | |
| 3293 | // ); | |
| 3294 | //} | |
| 3295 | // | |
| 3296 | //test "zig fmt: decimal float literals with underscore separators" { | |
| 3297 | // try testTransform( | |
| 3298 | // \\pub fn main() void { | |
| 3299 | // \\ const a:f64=(10.0e-0+(10.e+0))+10_00.00_00e-2+00_00.00_10e+4; | |
| 3300 | // \\ const b:f64=010.0--0_10.+0_1_0.0_0+1e2; | |
| 3301 | // \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3302 | // \\} | |
| 3303 | // , | |
| 3304 | // \\pub fn main() void { | |
| 3305 | // \\ const a: f64 = (10.0e-0 + (10.e+0)) + 10_00.00_00e-2 + 00_00.00_10e+4; | |
| 3306 | // \\ const b: f64 = 010.0 - -0_10. + 0_1_0.0_0 + 1e2; | |
| 3307 | // \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3308 | // \\} | |
| 3309 | // \\ | |
| 3310 | // ); | |
| 3311 | //} | |
| 3312 | // | |
| 3313 | //test "zig fmt: hexadeciaml float literals with underscore separators" { | |
| 3314 | // try testTransform( | |
| 3315 | // \\pub fn main() void { | |
| 3316 | // \\ const a: f64 = (0x10.0p-0+(0x10.p+0))+0x10_00.00_00p-8+0x00_00.00_10p+16; | |
| 3317 | // \\ const b: f64 = 0x0010.0--0x00_10.+0x10.00+0x1p4; | |
| 3318 | // \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3319 | // \\} | |
| 3320 | // , | |
| 3321 | // \\pub fn main() void { | |
| 3322 | // \\ const a: f64 = (0x10.0p-0 + (0x10.p+0)) + 0x10_00.00_00p-8 + 0x00_00.00_10p+16; | |
| 3323 | // \\ const b: f64 = 0x0010.0 - -0x00_10. + 0x10.00 + 0x1p4; | |
| 3324 | // \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); | |
| 3325 | // \\} | |
| 3326 | // \\ | |
| 3327 | // ); | |
| 3328 | //} | |
| 3329 | // | |
| 3330 | //test "zig fmt: convert async fn into callconv(.Async)" { | |
| 3331 | // try testTransform( | |
| 3332 | // \\async fn foo() void {} | |
| 3333 | // , | |
| 3334 | // \\fn foo() callconv(.Async) void {} | |
| 3335 | // \\ | |
| 3336 | // ); | |
| 3337 | //} | |
| 3338 | // | |
| 3339 | //test "zig fmt: convert extern fn proto into callconv(.C)" { | |
| 3340 | // try testTransform( | |
| 3341 | // \\extern fn foo0() void {} | |
| 3342 | // \\const foo1 = extern fn () void; | |
| 3343 | // , | |
| 3344 | // \\extern fn foo0() void {} | |
| 3345 | // \\const foo1 = fn () callconv(.C) void; | |
| 3346 | // \\ | |
| 3347 | // ); | |
| 3348 | //} | |
| 3349 | // | |
| 3350 | //test "zig fmt: C var args" { | |
| 3351 | // try testCanonical( | |
| 3352 | // \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; | |
| 3353 | // \\ | |
| 3354 | // ); | |
| 3355 | //} | |
| 3356 | // | |
| 3357 | //test "zig fmt: Only indent multiline string literals in function calls" { | |
| 3358 | // try testCanonical( | |
| 3359 | // \\test "zig fmt:" { | |
| 3360 | // \\ try testTransform( | |
| 3361 | // \\ \\const X = struct { | |
| 3362 | // \\ \\ foo: i32, bar: i8 }; | |
| 3363 | // \\ , | |
| 3364 | // \\ \\const X = struct { | |
| 3365 | // \\ \\ foo: i32, bar: i8 | |
| 3366 | // \\ \\}; | |
| 3367 | // \\ \\ | |
| 3368 | // \\ ); | |
| 3369 | // \\} | |
| 3370 | // \\ | |
| 3371 | // ); | |
| 3372 | //} | |
| 3373 | // | |
| 3374 | //test "zig fmt: Don't add extra newline after if" { | |
| 3375 | // try testCanonical( | |
| 3376 | // \\pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { | |
| 3377 | // \\ if (cwd().symLink(existing_path, new_path, .{})) { | |
| 3378 | // \\ return; | |
| 3379 | // \\ } | |
| 3380 | // \\} | |
| 3381 | // \\ | |
| 3382 | // ); | |
| 3383 | //} | |
| 3384 | // | |
| 3385 | //test "zig fmt: comments in ternary ifs" { | |
| 3386 | // try testCanonical( | |
| 3387 | // \\const x = if (true) { | |
| 3388 | // \\ 1; | |
| 3389 | // \\} else if (false) | |
| 3390 | // \\ // Comment | |
| 3391 | // \\ 0; | |
| 3392 | // \\const y = if (true) | |
| 3393 | // \\ // Comment | |
| 3394 | // \\ 1 | |
| 3395 | // \\else | |
| 3396 | // \\ 0; | |
| 3397 | // \\ | |
| 3398 | // \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; | |
| 3399 | // \\ | |
| 3400 | // ); | |
| 3401 | //} | |
| 3402 | // | |
| 3403 | //test "zig fmt: test comments in field access chain" { | |
| 3404 | // try testCanonical( | |
| 3405 | // \\pub const str = struct { | |
| 3406 | // \\ pub const Thing = more.more // | |
| 3407 | // \\ .more() // | |
| 3408 | // \\ .more().more() // | |
| 3409 | // \\ .more() // | |
| 3410 | // \\ // .more() // | |
| 3411 | // \\ .more() // | |
| 3412 | // \\ .more(); | |
| 3413 | // \\ data: Data, | |
| 3414 | // \\}; | |
| 3415 | // \\ | |
| 3416 | // \\pub const str = struct { | |
| 3417 | // \\ pub const Thing = more.more // | |
| 3418 | // \\ .more() // | |
| 3419 | // \\ // .more() // | |
| 3420 | // \\ // .more() // | |
| 3421 | // \\ // .more() // | |
| 3422 | // \\ .more() // | |
| 3423 | // \\ .more(); | |
| 3424 | // \\ data: Data, | |
| 3425 | // \\}; | |
| 3426 | // \\ | |
| 3427 | // \\pub const str = struct { | |
| 3428 | // \\ pub const Thing = more // | |
| 3429 | // \\ .more // | |
| 3430 | // \\ .more() // | |
| 3431 | // \\ .more(); | |
| 3432 | // \\ data: Data, | |
| 3433 | // \\}; | |
| 3434 | // \\ | |
| 3435 | // ); | |
| 3436 | //} | |
| 3437 | // | |
| 3438 | //test "zig fmt: Indent comma correctly after multiline string literals in arg list (trailing comma)" { | |
| 3439 | // try testCanonical( | |
| 3440 | // \\fn foo() void { | |
| 3441 | // \\ z.display_message_dialog( | |
| 3442 | // \\ *const [323:0]u8, | |
| 3443 | // \\ \\Message Text | |
| 3444 | // \\ \\------------ | |
| 3445 | // \\ \\xxxxxxxxxxxx | |
| 3446 | // \\ \\xxxxxxxxxxxx | |
| 3447 | // \\ , | |
| 3448 | // \\ g.GtkMessageType.GTK_MESSAGE_WARNING, | |
| 3449 | // \\ null, | |
| 3450 | // \\ ); | |
| 3451 | // \\ | |
| 3452 | // \\ z.display_message_dialog(*const [323:0]u8, | |
| 3453 | // \\ \\Message Text | |
| 3454 | // \\ \\------------ | |
| 3455 | // \\ \\xxxxxxxxxxxx | |
| 3456 | // \\ \\xxxxxxxxxxxx | |
| 3457 | // \\ , g.GtkMessageType.GTK_MESSAGE_WARNING, null); | |
| 3458 | // \\} | |
| 3459 | // \\ | |
| 3460 | // ); | |
| 3461 | //} | |
| 3462 | // | |
| 3463 | //test "zig fmt: Control flow statement as body of blockless if" { | |
| 3464 | // try testCanonical( | |
| 3465 | // \\pub fn main() void { | |
| 3466 | // \\ const zoom_node = if (focused_node == layout_first) | |
| 3467 | // \\ if (it.next()) { | |
| 3468 | // \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3469 | // \\ } else null | |
| 3470 | // \\ else | |
| 3471 | // \\ focused_node; | |
| 3472 | // \\ | |
| 3473 | // \\ const zoom_node = if (focused_node == layout_first) while (it.next()) |node| { | |
| 3474 | // \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3475 | // \\ } else null else | |
| 3476 | // \\ focused_node; | |
| 3477 | // \\ | |
| 3478 | // \\ const zoom_node = if (focused_node == layout_first) | |
| 3479 | // \\ if (it.next()) { | |
| 3480 | // \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3481 | // \\ } else null; | |
| 3482 | // \\ | |
| 3483 | // \\ const zoom_node = if (focused_node == layout_first) while (it.next()) |node| { | |
| 3484 | // \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; | |
| 3485 | // \\ }; | |
| 3486 | // \\ | |
| 3487 | // \\ const zoom_node = if (focused_node == layout_first) for (nodes) |node| { | |
| 3488 | // \\ break node; | |
| 3489 | // \\ }; | |
| 3490 | // \\ | |
| 3491 | // \\ const zoom_node = if (focused_node == layout_first) switch (nodes) { | |
| 3492 | // \\ 0 => 0, | |
| 3493 | // \\ } else | |
| 3494 | // \\ focused_node; | |
| 3495 | // \\} | |
| 3496 | // \\ | |
| 3497 | // ); | |
| 3498 | //} | |
| 3499 | // | |
| 3500 | //test "zig fmt: " { | |
| 3501 | // try testCanonical( | |
| 3502 | // \\pub fn sendViewTags(self: Self) void { | |
| 3503 | // \\ var it = ViewStack(View).iterator(self.output.views.first, std.math.maxInt(u32)); | |
| 3504 | // \\ while (it.next()) |node| | |
| 3505 | // \\ view_tags.append(node.view.current_tags) catch { | |
| 3506 | // \\ c.wl_resource_post_no_memory(self.wl_resource); | |
| 3507 | // \\ log.crit(.river_status, "out of memory", .{}); | |
| 3508 | // \\ return; | |
| 3509 | // \\ }; | |
| 3510 | // \\} | |
| 3511 | // \\ | |
| 3512 | // ); | |
| 3513 | //} | |
| 3514 | // | |
| 3515 | //test "zig fmt: allow trailing line comments to do manual array formatting" { | |
| 3516 | // try testCanonical( | |
| 3517 | // \\fn foo() void { | |
| 3518 | // \\ self.code.appendSliceAssumeCapacity(&[_]u8{ | |
| 3519 | // \\ 0x55, // push rbp | |
| 3520 | // \\ 0x48, 0x89, 0xe5, // mov rbp, rsp | |
| 3521 | // \\ 0x48, 0x81, 0xec, // sub rsp, imm32 (with reloc) | |
| 3522 | // \\ }); | |
| 3523 | // \\ | |
| 3524 | // \\ di_buf.appendAssumeCapacity(&[_]u8{ | |
| 3525 | // \\ 1, DW.TAG_compile_unit, DW.CHILDREN_no, // header | |
| 3526 | // \\ DW.AT_stmt_list, DW_FORM_data4, // form value pairs | |
| 3527 | // \\ DW.AT_low_pc, DW_FORM_addr, | |
| 3528 | // \\ DW.AT_high_pc, DW_FORM_addr, | |
| 3529 | // \\ DW.AT_name, DW_FORM_strp, | |
| 3530 | // \\ DW.AT_comp_dir, DW_FORM_strp, | |
| 3531 | // \\ DW.AT_producer, DW_FORM_strp, | |
| 3532 | // \\ DW.AT_language, DW_FORM_data2, | |
| 3533 | // \\ 0, 0, // sentinel | |
| 3534 | // \\ }); | |
| 3535 | // \\ | |
| 3536 | // \\ self.code.appendSliceAssumeCapacity(&[_]u8{ | |
| 3537 | // \\ 0x55, // push rbp | |
| 3538 | // \\ 0x48, 0x89, 0xe5, // mov rbp, rsp | |
| 3539 | // \\ // How do we handle this? | |
| 3540 | // \\ //0x48, 0x81, 0xec, // sub rsp, imm32 (with reloc) | |
| 3541 | // \\ // Here's a blank line, should that be allowed? | |
| 3542 | // \\ | |
| 3543 | // \\ 0x48, 0x89, 0xe5, | |
| 3544 | // \\ 0x33, 0x45, | |
| 3545 | // \\ // Now the comment breaks a single line -- how do we handle this? | |
| 3546 | // \\ 0x88, | |
| 3547 | // \\ }); | |
| 3548 | // \\} | |
| 3549 | // \\ | |
| 3550 | // ); | |
| 3551 | //} | |
| 3552 | // | |
| 3553 | //test "zig fmt: multiline string literals should play nice with array initializers" { | |
| 3554 | // try testCanonical( | |
| 3555 | // \\fn main() void { | |
| 3556 | // \\ var a = .{.{.{.{.{.{.{.{ | |
| 3557 | // \\ 0, | |
| 3558 | // \\ }}}}}}}}; | |
| 3559 | // \\ myFunc(.{ | |
| 3560 | // \\ "aaaaaaa", "bbbbbb", "ccccc", | |
| 3561 | // \\ "dddd", ("eee"), ("fff"), | |
| 3562 | // \\ ("gggg"), | |
| 3563 | // \\ // Line comment | |
| 3564 | // \\ \\Multiline String Literals can be quite long | |
| 3565 | // \\ , | |
| 3566 | // \\ \\Multiline String Literals can be quite long | |
| 3567 | // \\ \\Multiline String Literals can be quite long | |
| 3568 | // \\ , | |
| 3569 | // \\ \\Multiline String Literals can be quite long | |
| 3570 | // \\ \\Multiline String Literals can be quite long | |
| 3571 | // \\ \\Multiline String Literals can be quite long | |
| 3572 | // \\ \\Multiline String Literals can be quite long | |
| 3573 | // \\ , | |
| 3574 | // \\ ( | |
| 3575 | // \\ \\Multiline String Literals can be quite long | |
| 3576 | // \\ ), | |
| 3577 | // \\ .{ | |
| 3578 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3579 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3580 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3581 | // \\ }, | |
| 3582 | // \\ .{( | |
| 3583 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3584 | // \\ )}, | |
| 3585 | // \\ .{ | |
| 3586 | // \\ "xxxxxxx", "xxx", | |
| 3587 | // \\ ( | |
| 3588 | // \\ \\ xxx | |
| 3589 | // \\ ), | |
| 3590 | // \\ "xxx", "xxx", | |
| 3591 | // \\ }, | |
| 3592 | // \\ .{ "xxxxxxx", "xxx", "xxx", "xxx" }, .{ "xxxxxxx", "xxx", "xxx", "xxx" }, | |
| 3593 | // \\ "aaaaaaa", "bbbbbb", "ccccc", // - | |
| 3594 | // \\ "dddd", ("eee"), ("fff"), | |
| 3595 | // \\ .{ | |
| 3596 | // \\ "xxx", "xxx", | |
| 3597 | // \\ ( | |
| 3598 | // \\ \\ xxx | |
| 3599 | // \\ ), | |
| 3600 | // \\ "xxxxxxxxxxxxxx", "xxx", | |
| 3601 | // \\ }, | |
| 3602 | // \\ .{ | |
| 3603 | // \\ ( | |
| 3604 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3605 | // \\ ), | |
| 3606 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3607 | // \\ }, | |
| 3608 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3609 | // \\ \\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
| 3610 | // \\ }); | |
| 3611 | // \\} | |
| 3612 | // \\ | |
| 3613 | // ); | |
| 3614 | //} | |
| 3615 | // | |
| 3616 | //test "zig fmt: use of comments and Multiline string literals may force the parameters over multiple lines" { | |
| 3617 | // try testCanonical( | |
| 3618 | // \\pub fn makeMemUndefined(qzz: []u8) i1 { | |
| 3619 | // \\ cases.add( // fixed bug #2032 | |
| 3620 | // \\ "compile diagnostic string for top level decl type", | |
| 3621 | // \\ \\export fn entry() void { | |
| 3622 | // \\ \\ var foo: u32 = @This(){}; | |
| 3623 | // \\ \\} | |
| 3624 | // \\ , &[_][]const u8{ | |
| 3625 | // \\ "tmp.zig:2:27: error: type 'u32' does not support array initialization", | |
| 3626 | // \\ }); | |
| 3627 | // \\ @compileError( | |
| 3628 | // \\ \\ unknown-length pointers and C pointers cannot be hashed deeply. | |
| 3629 | // \\ \\ Consider providing your own hash function. | |
| 3630 | // \\ \\ unknown-length pointers and C pointers cannot be hashed deeply. | |
| 3631 | // \\ \\ Consider providing your own hash function. | |
| 3632 | // \\ ); | |
| 3633 | // \\ return @intCast(i1, doMemCheckClientRequestExpr(0, // default return | |
| 3634 | // \\ .MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0)); | |
| 3635 | // \\} | |
| 3636 | // \\ | |
| 3637 | // \\// This looks like garbage don't do this | |
| 3638 | // \\const rparen = tree.prevToken( | |
| 3639 | // \\// the first token for the annotation expressions is the left | |
| 3640 | // \\// parenthesis, hence the need for two prevToken | |
| 3641 | // \\ if (fn_proto.getAlignExpr()) |align_expr| | |
| 3642 | // \\ tree.prevToken(tree.prevToken(align_expr.firstToken())) | |
| 3643 | // \\else if (fn_proto.getSectionExpr()) |section_expr| | |
| 3644 | // \\ tree.prevToken(tree.prevToken(section_expr.firstToken())) | |
| 3645 | // \\else if (fn_proto.getCallconvExpr()) |callconv_expr| | |
| 3646 | // \\ tree.prevToken(tree.prevToken(callconv_expr.firstToken())) | |
| 3647 | // \\else switch (fn_proto.return_type) { | |
| 3648 | // \\ .Explicit => |node| node.firstToken(), | |
| 3649 | // \\ .InferErrorSet => |node| tree.prevToken(node.firstToken()), | |
| 3650 | // \\ .Invalid => unreachable, | |
| 3651 | // \\}); | |
| 3652 | // \\ | |
| 3653 | // ); | |
| 3654 | //} | |
| 3655 | // | |
| 3656 | //test "zig fmt: single argument trailing commas in @builtins()" { | |
| 3657 | // try testCanonical( | |
| 3658 | // \\pub fn foo(qzz: []u8) i1 { | |
| 3659 | // \\ @panic( | |
| 3660 | // \\ foo, | |
| 3661 | // \\ ); | |
| 3662 | // \\ panic( | |
| 3663 | // \\ foo, | |
| 3664 | // \\ ); | |
| 3665 | // \\ @panic( | |
| 3666 | // \\ foo, | |
| 3667 | // \\ bar, | |
| 3668 | // \\ ); | |
| 3669 | // \\} | |
| 3670 | // \\ | |
| 3671 | // ); | |
| 3672 | //} | |
| 3673 | // | |
| 3674 | //test "zig fmt: trailing comma should force multiline 1 column" { | |
| 3675 | // try testTransform( | |
| 3676 | // \\pub const UUID_NULL: uuid_t = [16]u8{0,0,0,0,}; | |
| 3677 | // \\ | |
| 3678 | // , | |
| 3679 | // \\pub const UUID_NULL: uuid_t = [16]u8{ | |
| 3680 | // \\ 0, | |
| 3681 | // \\ 0, | |
| 3682 | // \\ 0, | |
| 3683 | // \\ 0, | |
| 3684 | // \\}; | |
| 3685 | // \\ | |
| 3686 | // ); | |
| 3687 | //} | |
| 3688 | // | |
| 3689 | //test "zig fmt: function params should align nicely" { | |
| 3690 | // try testCanonical( | |
| 3691 | // \\pub fn foo() void { | |
| 3692 | // \\ cases.addRuntimeSafety("slicing operator with sentinel", | |
| 3693 | // \\ \\const std = @import("std"); | |
| 3694 | // \\ ++ check_panic_msg ++ | |
| 3695 | // \\ \\pub fn main() void { | |
| 3696 | // \\ \\ var buf = [4]u8{'a','b','c',0}; | |
| 3697 | // \\ \\ const slice = buf[0..:0]; | |
| 3698 | // \\ \\} | |
| 3699 | // \\ ); | |
| 3700 | // \\} | |
| 3701 | // \\ | |
| 3702 | // ); | |
| 3703 | //} | |
| 3727 | 3704 | |
| 3728 | 3705 | const std = @import("std"); |
| 3729 | 3706 | const mem = std.mem; |
| ... | ... | @@ -3763,8 +3740,10 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b |
| 3763 | 3740 | errdefer buffer.deinit(); |
| 3764 | 3741 | |
| 3765 | 3742 | const writer = buffer.writer(); |
| 3766 | anything_changed.* = try std.zig.render(allocator, writer, tree); | |
| 3767 | return buffer.toOwnedSlice(); | |
| 3743 | try std.zig.render(allocator, writer, tree); | |
| 3744 | const result = buffer.toOwnedSlice(); | |
| 3745 | anything_changed.* = !mem.eql(u8, result, source); | |
| 3746 | return result; | |
| 3768 | 3747 | } |
| 3769 | 3748 | fn testTransform(source: []const u8, expected_source: []const u8) !void { |
| 3770 | 3749 | const needed_alloc_count = x: { |
lib/std/zig/render.zig+2128-2341| ... | ... | @@ -14,2167 +14,2072 @@ const indent_delta = 4; |
| 14 | 14 | const asm_indent_delta = 2; |
| 15 | 15 | |
| 16 | 16 | pub const Error = error{ |
| 17 | /// Ran out of memory allocating call stack frames to complete rendering. | |
| 17 | /// Ran out of memory allocating call stack frames to complete rendering, or | |
| 18 | /// ran out of memory allocating space in the output buffer. | |
| 18 | 19 | OutOfMemory, |
| 19 | 20 | }; |
| 20 | 21 | |
| 21 | /// Returns whether anything changed | |
| 22 | pub fn render(allocator: *mem.Allocator, stream: anytype, tree: *ast.Tree) (@TypeOf(stream).Error || Error)!bool { | |
| 23 | // cannot render an invalid tree | |
| 24 | std.debug.assert(tree.errors.len == 0); | |
| 22 | const Writer = std.ArrayList(u8).Writer; | |
| 23 | const Ais = std.io.AutoIndentingStream(Writer); | |
| 25 | 24 | |
| 26 | var change_detection_stream = std.io.changeDetectionStream(tree.source, stream); | |
| 27 | var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, change_detection_stream.writer()); | |
| 28 | ||
| 29 | try renderRoot(allocator, &auto_indenting_stream, tree); | |
| 30 | ||
| 31 | return change_detection_stream.changeDetected(); | |
| 32 | } | |
| 33 | ||
| 34 | fn renderRoot( | |
| 35 | allocator: *mem.Allocator, | |
| 36 | ais: anytype, | |
| 37 | tree: *ast.Tree, | |
| 38 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 39 | ||
| 40 | // render all the line comments at the beginning of the file | |
| 41 | for (tree.token_ids) |token_id, i| { | |
| 42 | if (token_id != .LineComment) break; | |
| 43 | const token_loc = tree.token_locs[i]; | |
| 44 | try ais.writer().print("{s}\n", .{mem.trimRight(u8, tree.tokenSliceLoc(token_loc), " ")}); | |
| 45 | const next_token = tree.token_locs[i + 1]; | |
| 46 | const loc = tree.tokenLocationLoc(token_loc.end, next_token); | |
| 47 | if (loc.line >= 2) { | |
| 48 | try ais.insertNewline(); | |
| 49 | } | |
| 50 | } | |
| 51 | ||
| 52 | var decl_i: ast.NodeIndex = 0; | |
| 53 | const root_decls = tree.root_node.decls(); | |
| 54 | ||
| 55 | if (root_decls.len == 0) return; | |
| 56 | while (true) { | |
| 57 | var decl = root_decls[decl_i]; | |
| 58 | ||
| 59 | // This loop does the following: | |
| 60 | // | |
| 61 | // - Iterates through line/doc comment tokens that precedes the current | |
| 62 | // decl. | |
| 63 | // - Figures out the first token index (`copy_start_token_index`) which | |
| 64 | // hasn't been copied to the output stream yet. | |
| 65 | // - Detects `zig fmt: (off|on)` in the line comment tokens, and | |
| 66 | // determines whether the current decl should be reformatted or not. | |
| 67 | // | |
| 68 | var token_index = decl.firstToken(); | |
| 69 | var fmt_active = true; | |
| 70 | var found_fmt_directive = false; | |
| 71 | ||
| 72 | var copy_start_token_index = token_index; | |
| 73 | ||
| 74 | while (token_index != 0) { | |
| 75 | token_index -= 1; | |
| 76 | const token_id = tree.token_ids[token_index]; | |
| 77 | switch (token_id) { | |
| 78 | .LineComment => {}, | |
| 79 | .DocComment => { | |
| 80 | copy_start_token_index = token_index; | |
| 81 | continue; | |
| 82 | }, | |
| 83 | else => break, | |
| 84 | } | |
| 85 | ||
| 86 | const token_loc = tree.token_locs[token_index]; | |
| 87 | if (mem.eql(u8, mem.trim(u8, tree.tokenSliceLoc(token_loc)[2..], " "), "zig fmt: off")) { | |
| 88 | if (!found_fmt_directive) { | |
| 89 | fmt_active = false; | |
| 90 | found_fmt_directive = true; | |
| 91 | } | |
| 92 | } else if (mem.eql(u8, mem.trim(u8, tree.tokenSliceLoc(token_loc)[2..], " "), "zig fmt: on")) { | |
| 93 | if (!found_fmt_directive) { | |
| 94 | fmt_active = true; | |
| 95 | found_fmt_directive = true; | |
| 96 | } | |
| 97 | } | |
| 98 | } | |
| 99 | ||
| 100 | if (!fmt_active) { | |
| 101 | // Reformatting is disabled for the current decl and possibly some | |
| 102 | // more decls that follow. | |
| 103 | // Find the next `decl` for which reformatting is re-enabled. | |
| 104 | token_index = decl.firstToken(); | |
| 105 | ||
| 106 | while (!fmt_active) { | |
| 107 | decl_i += 1; | |
| 108 | if (decl_i >= root_decls.len) { | |
| 109 | // If there's no next reformatted `decl`, just copy the | |
| 110 | // remaining input tokens and bail out. | |
| 111 | const start = tree.token_locs[copy_start_token_index].start; | |
| 112 | try copyFixingWhitespace(ais, tree.source[start..]); | |
| 113 | return; | |
| 114 | } | |
| 115 | decl = root_decls[decl_i]; | |
| 116 | var decl_first_token_index = decl.firstToken(); | |
| 117 | ||
| 118 | while (token_index < decl_first_token_index) : (token_index += 1) { | |
| 119 | const token_id = tree.token_ids[token_index]; | |
| 120 | switch (token_id) { | |
| 121 | .LineComment => {}, | |
| 122 | .Eof => unreachable, | |
| 123 | else => continue, | |
| 124 | } | |
| 125 | const token_loc = tree.token_locs[token_index]; | |
| 126 | if (mem.eql(u8, mem.trim(u8, tree.tokenSliceLoc(token_loc)[2..], " "), "zig fmt: on")) { | |
| 127 | fmt_active = true; | |
| 128 | } else if (mem.eql(u8, mem.trim(u8, tree.tokenSliceLoc(token_loc)[2..], " "), "zig fmt: off")) { | |
| 129 | fmt_active = false; | |
| 130 | } | |
| 131 | } | |
| 132 | } | |
| 133 | ||
| 134 | // Found the next `decl` for which reformatting is enabled. Copy | |
| 135 | // the input tokens before the `decl` that haven't been copied yet. | |
| 136 | var copy_end_token_index = decl.firstToken(); | |
| 137 | token_index = copy_end_token_index; | |
| 138 | while (token_index != 0) { | |
| 139 | token_index -= 1; | |
| 140 | const token_id = tree.token_ids[token_index]; | |
| 141 | switch (token_id) { | |
| 142 | .LineComment => {}, | |
| 143 | .DocComment => { | |
| 144 | copy_end_token_index = token_index; | |
| 145 | continue; | |
| 146 | }, | |
| 147 | else => break, | |
| 148 | } | |
| 149 | } | |
| 150 | ||
| 151 | const start = tree.token_locs[copy_start_token_index].start; | |
| 152 | const end = tree.token_locs[copy_end_token_index].start; | |
| 153 | try copyFixingWhitespace(ais, tree.source[start..end]); | |
| 154 | } | |
| 155 | ||
| 156 | try renderTopLevelDecl(allocator, ais, tree, decl); | |
| 157 | decl_i += 1; | |
| 158 | if (decl_i >= root_decls.len) return; | |
| 159 | try renderExtraNewline(tree, ais, root_decls[decl_i]); | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 163 | fn renderExtraNewline(tree: *ast.Tree, ais: anytype, node: *ast.Node) @TypeOf(ais.*).Error!void { | |
| 164 | return renderExtraNewlineToken(tree, ais, node.firstToken()); | |
| 165 | } | |
| 166 | ||
| 167 | fn renderExtraNewlineToken( | |
| 168 | tree: *ast.Tree, | |
| 169 | ais: anytype, | |
| 170 | first_token: ast.TokenIndex, | |
| 171 | ) @TypeOf(ais.*).Error!void { | |
| 172 | var prev_token = first_token; | |
| 173 | if (prev_token == 0) return; | |
| 174 | var newline_threshold: usize = 2; | |
| 175 | while (tree.token_ids[prev_token - 1] == .DocComment) { | |
| 176 | if (tree.tokenLocation(tree.token_locs[prev_token - 1].end, prev_token).line == 1) { | |
| 177 | newline_threshold += 1; | |
| 178 | } | |
| 179 | prev_token -= 1; | |
| 180 | } | |
| 181 | const prev_token_end = tree.token_locs[prev_token - 1].end; | |
| 182 | const loc = tree.tokenLocation(prev_token_end, first_token); | |
| 183 | if (loc.line >= newline_threshold) { | |
| 184 | try ais.insertNewline(); | |
| 185 | } | |
| 186 | } | |
| 187 | ||
| 188 | fn renderTopLevelDecl(allocator: *mem.Allocator, ais: anytype, tree: *ast.Tree, decl: *ast.Node) (@TypeOf(ais.*).Error || Error)!void { | |
| 189 | try renderContainerDecl(allocator, ais, tree, decl, .Newline); | |
| 190 | } | |
| 191 | ||
| 192 | fn renderContainerDecl(allocator: *mem.Allocator, ais: anytype, tree: *ast.Tree, decl: *ast.Node, space: Space) (@TypeOf(ais.*).Error || Error)!void { | |
| 193 | switch (decl.tag) { | |
| 194 | .FnProto => { | |
| 195 | const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl); | |
| 196 | ||
| 197 | try renderDocComments(tree, ais, fn_proto, fn_proto.getDocComments()); | |
| 198 | ||
| 199 | if (fn_proto.getBodyNode()) |body_node| { | |
| 200 | try renderExpression(allocator, ais, tree, decl, .Space); | |
| 201 | try renderExpression(allocator, ais, tree, body_node, space); | |
| 202 | } else { | |
| 203 | try renderExpression(allocator, ais, tree, decl, .None); | |
| 204 | try renderToken(tree, ais, tree.nextToken(decl.lastToken()), space); | |
| 205 | } | |
| 206 | }, | |
| 207 | ||
| 208 | .Use => { | |
| 209 | const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl); | |
| 210 | ||
| 211 | if (use_decl.visib_token) |visib_token| { | |
| 212 | try renderToken(tree, ais, visib_token, .Space); // pub | |
| 213 | } | |
| 214 | try renderToken(tree, ais, use_decl.use_token, .Space); // usingnamespace | |
| 215 | try renderExpression(allocator, ais, tree, use_decl.expr, .None); | |
| 216 | try renderToken(tree, ais, use_decl.semicolon_token, space); // ; | |
| 217 | }, | |
| 218 | ||
| 219 | .VarDecl => { | |
| 220 | const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl); | |
| 221 | ||
| 222 | try renderDocComments(tree, ais, var_decl, var_decl.getDocComments()); | |
| 223 | try renderVarDecl(allocator, ais, tree, var_decl); | |
| 224 | }, | |
| 225 | ||
| 226 | .TestDecl => { | |
| 227 | const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl); | |
| 228 | ||
| 229 | try renderDocComments(tree, ais, test_decl, test_decl.doc_comments); | |
| 230 | try renderToken(tree, ais, test_decl.test_token, .Space); | |
| 231 | if (test_decl.name) |name| | |
| 232 | try renderExpression(allocator, ais, tree, name, .Space); | |
| 233 | try renderExpression(allocator, ais, tree, test_decl.body_node, space); | |
| 234 | }, | |
| 235 | ||
| 236 | .ContainerField => { | |
| 237 | const field = @fieldParentPtr(ast.Node.ContainerField, "base", decl); | |
| 238 | ||
| 239 | try renderDocComments(tree, ais, field, field.doc_comments); | |
| 240 | if (field.comptime_token) |t| { | |
| 241 | try renderToken(tree, ais, t, .Space); // comptime | |
| 242 | } | |
| 243 | ||
| 244 | const src_has_trailing_comma = blk: { | |
| 245 | const maybe_comma = tree.nextToken(field.lastToken()); | |
| 246 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 247 | }; | |
| 248 | ||
| 249 | // The trailing comma is emitted at the end, but if it's not present | |
| 250 | // we still have to respect the specified `space` parameter | |
| 251 | const last_token_space: Space = if (src_has_trailing_comma) .None else space; | |
| 252 | ||
| 253 | if (field.type_expr == null and field.value_expr == null) { | |
| 254 | try renderToken(tree, ais, field.name_token, last_token_space); // name | |
| 255 | } else if (field.type_expr != null and field.value_expr == null) { | |
| 256 | try renderToken(tree, ais, field.name_token, .None); // name | |
| 257 | try renderToken(tree, ais, tree.nextToken(field.name_token), .Space); // : | |
| 258 | ||
| 259 | if (field.align_expr) |align_value_expr| { | |
| 260 | try renderExpression(allocator, ais, tree, field.type_expr.?, .Space); // type | |
| 261 | const lparen_token = tree.prevToken(align_value_expr.firstToken()); | |
| 262 | const align_kw = tree.prevToken(lparen_token); | |
| 263 | const rparen_token = tree.nextToken(align_value_expr.lastToken()); | |
| 264 | try renderToken(tree, ais, align_kw, .None); // align | |
| 265 | try renderToken(tree, ais, lparen_token, .None); // ( | |
| 266 | try renderExpression(allocator, ais, tree, align_value_expr, .None); // alignment | |
| 267 | try renderToken(tree, ais, rparen_token, last_token_space); // ) | |
| 268 | } else { | |
| 269 | try renderExpression(allocator, ais, tree, field.type_expr.?, last_token_space); // type | |
| 270 | } | |
| 271 | } else if (field.type_expr == null and field.value_expr != null) { | |
| 272 | try renderToken(tree, ais, field.name_token, .Space); // name | |
| 273 | try renderToken(tree, ais, tree.nextToken(field.name_token), .Space); // = | |
| 274 | try renderExpression(allocator, ais, tree, field.value_expr.?, last_token_space); // value | |
| 275 | } else { | |
| 276 | try renderToken(tree, ais, field.name_token, .None); // name | |
| 277 | try renderToken(tree, ais, tree.nextToken(field.name_token), .Space); // : | |
| 278 | ||
| 279 | if (field.align_expr) |align_value_expr| { | |
| 280 | try renderExpression(allocator, ais, tree, field.type_expr.?, .Space); // type | |
| 281 | const lparen_token = tree.prevToken(align_value_expr.firstToken()); | |
| 282 | const align_kw = tree.prevToken(lparen_token); | |
| 283 | const rparen_token = tree.nextToken(align_value_expr.lastToken()); | |
| 284 | try renderToken(tree, ais, align_kw, .None); // align | |
| 285 | try renderToken(tree, ais, lparen_token, .None); // ( | |
| 286 | try renderExpression(allocator, ais, tree, align_value_expr, .None); // alignment | |
| 287 | try renderToken(tree, ais, rparen_token, .Space); // ) | |
| 288 | } else { | |
| 289 | try renderExpression(allocator, ais, tree, field.type_expr.?, .Space); // type | |
| 290 | } | |
| 291 | try renderToken(tree, ais, tree.prevToken(field.value_expr.?.firstToken()), .Space); // = | |
| 292 | try renderExpression(allocator, ais, tree, field.value_expr.?, last_token_space); // value | |
| 293 | } | |
| 294 | ||
| 295 | if (src_has_trailing_comma) { | |
| 296 | const comma = tree.nextToken(field.lastToken()); | |
| 297 | try renderToken(tree, ais, comma, space); | |
| 298 | } | |
| 299 | }, | |
| 300 | ||
| 301 | .Comptime => { | |
| 302 | assert(!decl.requireSemiColon()); | |
| 303 | try renderExpression(allocator, ais, tree, decl, space); | |
| 304 | }, | |
| 305 | ||
| 306 | .DocComment => { | |
| 307 | const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl); | |
| 308 | const kind = tree.token_ids[comment.first_line]; | |
| 309 | try renderToken(tree, ais, comment.first_line, .Newline); | |
| 310 | var tok_i = comment.first_line + 1; | |
| 311 | while (true) : (tok_i += 1) { | |
| 312 | const tok_id = tree.token_ids[tok_i]; | |
| 313 | if (tok_id == kind) { | |
| 314 | try renderToken(tree, ais, tok_i, .Newline); | |
| 315 | } else if (tok_id == .LineComment) { | |
| 316 | continue; | |
| 317 | } else { | |
| 318 | break; | |
| 319 | } | |
| 320 | } | |
| 321 | }, | |
| 322 | else => unreachable, | |
| 323 | } | |
| 324 | } | |
| 325 | ||
| 326 | fn renderExpression( | |
| 327 | allocator: *mem.Allocator, | |
| 328 | ais: anytype, | |
| 329 | tree: *ast.Tree, | |
| 330 | base: *ast.Node, | |
| 331 | space: Space, | |
| 332 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 333 | switch (base.tag) { | |
| 334 | .Identifier, | |
| 335 | .IntegerLiteral, | |
| 336 | .FloatLiteral, | |
| 337 | .StringLiteral, | |
| 338 | .CharLiteral, | |
| 339 | .BoolLiteral, | |
| 340 | .NullLiteral, | |
| 341 | .Unreachable, | |
| 342 | .ErrorType, | |
| 343 | .UndefinedLiteral, | |
| 344 | => { | |
| 345 | const casted_node = base.cast(ast.Node.OneToken).?; | |
| 346 | return renderToken(tree, ais, casted_node.token, space); | |
| 347 | }, | |
| 348 | ||
| 349 | .AnyType => { | |
| 350 | const any_type = base.castTag(.AnyType).?; | |
| 351 | if (mem.eql(u8, tree.tokenSlice(any_type.token), "var")) { | |
| 352 | // TODO remove in next release cycle | |
| 353 | try ais.writer().writeAll("anytype"); | |
| 354 | if (space == .Comma) try ais.writer().writeAll(",\n"); | |
| 355 | return; | |
| 356 | } | |
| 357 | return renderToken(tree, ais, any_type.token, space); | |
| 358 | }, | |
| 359 | ||
| 360 | .Block, .LabeledBlock => { | |
| 361 | const block: struct { | |
| 362 | label: ?ast.TokenIndex, | |
| 363 | statements: []*ast.Node, | |
| 364 | lbrace: ast.TokenIndex, | |
| 365 | rbrace: ast.TokenIndex, | |
| 366 | } = b: { | |
| 367 | if (base.castTag(.Block)) |block| { | |
| 368 | break :b .{ | |
| 369 | .label = null, | |
| 370 | .statements = block.statements(), | |
| 371 | .lbrace = block.lbrace, | |
| 372 | .rbrace = block.rbrace, | |
| 373 | }; | |
| 374 | } else if (base.castTag(.LabeledBlock)) |block| { | |
| 375 | break :b .{ | |
| 376 | .label = block.label, | |
| 377 | .statements = block.statements(), | |
| 378 | .lbrace = block.lbrace, | |
| 379 | .rbrace = block.rbrace, | |
| 380 | }; | |
| 381 | } else { | |
| 382 | unreachable; | |
| 383 | } | |
| 384 | }; | |
| 385 | ||
| 386 | if (block.label) |label| { | |
| 387 | try renderToken(tree, ais, label, Space.None); | |
| 388 | try renderToken(tree, ais, tree.nextToken(label), Space.Space); | |
| 389 | } | |
| 390 | ||
| 391 | if (block.statements.len == 0) { | |
| 392 | ais.pushIndentNextLine(); | |
| 393 | defer ais.popIndent(); | |
| 394 | try renderToken(tree, ais, block.lbrace, Space.None); | |
| 395 | } else { | |
| 396 | ais.pushIndentNextLine(); | |
| 397 | defer ais.popIndent(); | |
| 398 | ||
| 399 | try renderToken(tree, ais, block.lbrace, Space.Newline); | |
| 400 | ||
| 401 | for (block.statements) |statement, i| { | |
| 402 | try renderStatement(allocator, ais, tree, statement); | |
| 403 | ||
| 404 | if (i + 1 < block.statements.len) { | |
| 405 | try renderExtraNewline(tree, ais, block.statements[i + 1]); | |
| 406 | } | |
| 407 | } | |
| 408 | } | |
| 409 | return renderToken(tree, ais, block.rbrace, space); | |
| 410 | }, | |
| 411 | ||
| 412 | .Defer => { | |
| 413 | const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base); | |
| 414 | ||
| 415 | try renderToken(tree, ais, defer_node.defer_token, Space.Space); | |
| 416 | if (defer_node.payload) |payload| { | |
| 417 | try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 418 | } | |
| 419 | return renderExpression(allocator, ais, tree, defer_node.expr, space); | |
| 420 | }, | |
| 421 | .Comptime => { | |
| 422 | const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base); | |
| 423 | ||
| 424 | try renderToken(tree, ais, comptime_node.comptime_token, Space.Space); | |
| 425 | return renderExpression(allocator, ais, tree, comptime_node.expr, space); | |
| 426 | }, | |
| 427 | .Nosuspend => { | |
| 428 | const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base); | |
| 429 | if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) { | |
| 430 | // TODO: remove this | |
| 431 | try ais.writer().writeAll("nosuspend "); | |
| 432 | } else { | |
| 433 | try renderToken(tree, ais, nosuspend_node.nosuspend_token, Space.Space); | |
| 434 | } | |
| 435 | return renderExpression(allocator, ais, tree, nosuspend_node.expr, space); | |
| 436 | }, | |
| 437 | ||
| 438 | .Suspend => { | |
| 439 | const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base); | |
| 440 | ||
| 441 | if (suspend_node.body) |body| { | |
| 442 | try renderToken(tree, ais, suspend_node.suspend_token, Space.Space); | |
| 443 | return renderExpression(allocator, ais, tree, body, space); | |
| 444 | } else { | |
| 445 | return renderToken(tree, ais, suspend_node.suspend_token, space); | |
| 446 | } | |
| 447 | }, | |
| 448 | ||
| 449 | .Catch => { | |
| 450 | const infix_op_node = @fieldParentPtr(ast.Node.Catch, "base", base); | |
| 451 | ||
| 452 | const op_space = Space.Space; | |
| 453 | try renderExpression(allocator, ais, tree, infix_op_node.lhs, op_space); | |
| 454 | ||
| 455 | const after_op_space = blk: { | |
| 456 | const same_line = tree.tokensOnSameLine(infix_op_node.op_token, tree.nextToken(infix_op_node.op_token)); | |
| 457 | break :blk if (same_line) op_space else Space.Newline; | |
| 458 | }; | |
| 459 | ||
| 460 | try renderToken(tree, ais, infix_op_node.op_token, after_op_space); | |
| 461 | ||
| 462 | if (infix_op_node.payload) |payload| { | |
| 463 | try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 464 | } | |
| 465 | ||
| 466 | ais.pushIndentOneShot(); | |
| 467 | return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); | |
| 468 | }, | |
| 469 | ||
| 470 | .Add, | |
| 471 | .AddWrap, | |
| 472 | .ArrayCat, | |
| 473 | .ArrayMult, | |
| 474 | .Assign, | |
| 475 | .AssignBitAnd, | |
| 476 | .AssignBitOr, | |
| 477 | .AssignBitShiftLeft, | |
| 478 | .AssignBitShiftRight, | |
| 479 | .AssignBitXor, | |
| 480 | .AssignDiv, | |
| 481 | .AssignSub, | |
| 482 | .AssignSubWrap, | |
| 483 | .AssignMod, | |
| 484 | .AssignAdd, | |
| 485 | .AssignAddWrap, | |
| 486 | .AssignMul, | |
| 487 | .AssignMulWrap, | |
| 488 | .BangEqual, | |
| 489 | .BitAnd, | |
| 490 | .BitOr, | |
| 491 | .BitShiftLeft, | |
| 492 | .BitShiftRight, | |
| 493 | .BitXor, | |
| 494 | .BoolAnd, | |
| 495 | .BoolOr, | |
| 496 | .Div, | |
| 497 | .EqualEqual, | |
| 498 | .ErrorUnion, | |
| 499 | .GreaterOrEqual, | |
| 500 | .GreaterThan, | |
| 501 | .LessOrEqual, | |
| 502 | .LessThan, | |
| 503 | .MergeErrorSets, | |
| 504 | .Mod, | |
| 505 | .Mul, | |
| 506 | .MulWrap, | |
| 507 | .Period, | |
| 508 | .Range, | |
| 509 | .Sub, | |
| 510 | .SubWrap, | |
| 511 | .OrElse, | |
| 512 | => { | |
| 513 | const infix_op_node = @fieldParentPtr(ast.Node.SimpleInfixOp, "base", base); | |
| 514 | ||
| 515 | const op_space = switch (base.tag) { | |
| 516 | .Period, .ErrorUnion, .Range => Space.None, | |
| 517 | else => Space.Space, | |
| 518 | }; | |
| 519 | try renderExpression(allocator, ais, tree, infix_op_node.lhs, op_space); | |
| 520 | ||
| 521 | const after_op_space = blk: { | |
| 522 | const loc = tree.tokenLocation(tree.token_locs[infix_op_node.op_token].end, tree.nextToken(infix_op_node.op_token)); | |
| 523 | break :blk if (loc.line == 0) op_space else Space.Newline; | |
| 524 | }; | |
| 525 | ||
| 526 | { | |
| 527 | ais.pushIndent(); | |
| 528 | defer ais.popIndent(); | |
| 529 | try renderToken(tree, ais, infix_op_node.op_token, after_op_space); | |
| 530 | } | |
| 531 | ais.pushIndentOneShot(); | |
| 532 | return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); | |
| 533 | }, | |
| 534 | ||
| 535 | .BitNot, | |
| 536 | .BoolNot, | |
| 537 | .Negation, | |
| 538 | .NegationWrap, | |
| 539 | .OptionalType, | |
| 540 | .AddressOf, | |
| 541 | => { | |
| 542 | const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base); | |
| 543 | try renderToken(tree, ais, casted_node.op_token, Space.None); | |
| 544 | return renderExpression(allocator, ais, tree, casted_node.rhs, space); | |
| 545 | }, | |
| 546 | ||
| 547 | .Try, | |
| 548 | .Resume, | |
| 549 | .Await, | |
| 550 | => { | |
| 551 | const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base); | |
| 552 | try renderToken(tree, ais, casted_node.op_token, Space.Space); | |
| 553 | return renderExpression(allocator, ais, tree, casted_node.rhs, space); | |
| 554 | }, | |
| 555 | ||
| 556 | .ArrayType => { | |
| 557 | const array_type = @fieldParentPtr(ast.Node.ArrayType, "base", base); | |
| 558 | return renderArrayType( | |
| 559 | allocator, | |
| 560 | ais, | |
| 561 | tree, | |
| 562 | array_type.op_token, | |
| 563 | array_type.rhs, | |
| 564 | array_type.len_expr, | |
| 565 | null, | |
| 566 | space, | |
| 567 | ); | |
| 568 | }, | |
| 569 | .ArrayTypeSentinel => { | |
| 570 | const array_type = @fieldParentPtr(ast.Node.ArrayTypeSentinel, "base", base); | |
| 571 | return renderArrayType( | |
| 572 | allocator, | |
| 573 | ais, | |
| 574 | tree, | |
| 575 | array_type.op_token, | |
| 576 | array_type.rhs, | |
| 577 | array_type.len_expr, | |
| 578 | array_type.sentinel, | |
| 579 | space, | |
| 580 | ); | |
| 581 | }, | |
| 582 | ||
| 583 | .PtrType => { | |
| 584 | const ptr_type = @fieldParentPtr(ast.Node.PtrType, "base", base); | |
| 585 | const op_tok_id = tree.token_ids[ptr_type.op_token]; | |
| 586 | switch (op_tok_id) { | |
| 587 | .Asterisk, .AsteriskAsterisk => try ais.writer().writeByte('*'), | |
| 588 | .LBracket => if (tree.token_ids[ptr_type.op_token + 2] == .Identifier) | |
| 589 | try ais.writer().writeAll("[*c") | |
| 590 | else | |
| 591 | try ais.writer().writeAll("[*"), | |
| 592 | else => unreachable, | |
| 593 | } | |
| 594 | if (ptr_type.ptr_info.sentinel) |sentinel| { | |
| 595 | const colon_token = tree.prevToken(sentinel.firstToken()); | |
| 596 | try renderToken(tree, ais, colon_token, Space.None); // : | |
| 597 | const sentinel_space = switch (op_tok_id) { | |
| 598 | .LBracket => Space.None, | |
| 599 | else => Space.Space, | |
| 600 | }; | |
| 601 | try renderExpression(allocator, ais, tree, sentinel, sentinel_space); | |
| 602 | } | |
| 603 | switch (op_tok_id) { | |
| 604 | .Asterisk, .AsteriskAsterisk => {}, | |
| 605 | .LBracket => try ais.writer().writeByte(']'), | |
| 606 | else => unreachable, | |
| 607 | } | |
| 608 | if (ptr_type.ptr_info.allowzero_token) |allowzero_token| { | |
| 609 | try renderToken(tree, ais, allowzero_token, Space.Space); // allowzero | |
| 610 | } | |
| 611 | if (ptr_type.ptr_info.align_info) |align_info| { | |
| 612 | const lparen_token = tree.prevToken(align_info.node.firstToken()); | |
| 613 | const align_token = tree.prevToken(lparen_token); | |
| 614 | ||
| 615 | try renderToken(tree, ais, align_token, Space.None); // align | |
| 616 | try renderToken(tree, ais, lparen_token, Space.None); // ( | |
| 617 | ||
| 618 | try renderExpression(allocator, ais, tree, align_info.node, Space.None); | |
| 619 | ||
| 620 | if (align_info.bit_range) |bit_range| { | |
| 621 | const colon1 = tree.prevToken(bit_range.start.firstToken()); | |
| 622 | const colon2 = tree.prevToken(bit_range.end.firstToken()); | |
| 623 | ||
| 624 | try renderToken(tree, ais, colon1, Space.None); // : | |
| 625 | try renderExpression(allocator, ais, tree, bit_range.start, Space.None); | |
| 626 | try renderToken(tree, ais, colon2, Space.None); // : | |
| 627 | try renderExpression(allocator, ais, tree, bit_range.end, Space.None); | |
| 628 | ||
| 629 | const rparen_token = tree.nextToken(bit_range.end.lastToken()); | |
| 630 | try renderToken(tree, ais, rparen_token, Space.Space); // ) | |
| 631 | } else { | |
| 632 | const rparen_token = tree.nextToken(align_info.node.lastToken()); | |
| 633 | try renderToken(tree, ais, rparen_token, Space.Space); // ) | |
| 634 | } | |
| 635 | } | |
| 636 | if (ptr_type.ptr_info.const_token) |const_token| { | |
| 637 | try renderToken(tree, ais, const_token, Space.Space); // const | |
| 638 | } | |
| 639 | if (ptr_type.ptr_info.volatile_token) |volatile_token| { | |
| 640 | try renderToken(tree, ais, volatile_token, Space.Space); // volatile | |
| 641 | } | |
| 642 | return renderExpression(allocator, ais, tree, ptr_type.rhs, space); | |
| 643 | }, | |
| 644 | ||
| 645 | .SliceType => { | |
| 646 | const slice_type = @fieldParentPtr(ast.Node.SliceType, "base", base); | |
| 647 | try renderToken(tree, ais, slice_type.op_token, Space.None); // [ | |
| 648 | if (slice_type.ptr_info.sentinel) |sentinel| { | |
| 649 | const colon_token = tree.prevToken(sentinel.firstToken()); | |
| 650 | try renderToken(tree, ais, colon_token, Space.None); // : | |
| 651 | try renderExpression(allocator, ais, tree, sentinel, Space.None); | |
| 652 | try renderToken(tree, ais, tree.nextToken(sentinel.lastToken()), Space.None); // ] | |
| 653 | } else { | |
| 654 | try renderToken(tree, ais, tree.nextToken(slice_type.op_token), Space.None); // ] | |
| 655 | } | |
| 656 | ||
| 657 | if (slice_type.ptr_info.allowzero_token) |allowzero_token| { | |
| 658 | try renderToken(tree, ais, allowzero_token, Space.Space); // allowzero | |
| 659 | } | |
| 660 | if (slice_type.ptr_info.align_info) |align_info| { | |
| 661 | const lparen_token = tree.prevToken(align_info.node.firstToken()); | |
| 662 | const align_token = tree.prevToken(lparen_token); | |
| 663 | ||
| 664 | try renderToken(tree, ais, align_token, Space.None); // align | |
| 665 | try renderToken(tree, ais, lparen_token, Space.None); // ( | |
| 666 | ||
| 667 | try renderExpression(allocator, ais, tree, align_info.node, Space.None); | |
| 668 | ||
| 669 | if (align_info.bit_range) |bit_range| { | |
| 670 | const colon1 = tree.prevToken(bit_range.start.firstToken()); | |
| 671 | const colon2 = tree.prevToken(bit_range.end.firstToken()); | |
| 672 | ||
| 673 | try renderToken(tree, ais, colon1, Space.None); // : | |
| 674 | try renderExpression(allocator, ais, tree, bit_range.start, Space.None); | |
| 675 | try renderToken(tree, ais, colon2, Space.None); // : | |
| 676 | try renderExpression(allocator, ais, tree, bit_range.end, Space.None); | |
| 677 | ||
| 678 | const rparen_token = tree.nextToken(bit_range.end.lastToken()); | |
| 679 | try renderToken(tree, ais, rparen_token, Space.Space); // ) | |
| 680 | } else { | |
| 681 | const rparen_token = tree.nextToken(align_info.node.lastToken()); | |
| 682 | try renderToken(tree, ais, rparen_token, Space.Space); // ) | |
| 683 | } | |
| 684 | } | |
| 685 | if (slice_type.ptr_info.const_token) |const_token| { | |
| 686 | try renderToken(tree, ais, const_token, Space.Space); | |
| 687 | } | |
| 688 | if (slice_type.ptr_info.volatile_token) |volatile_token| { | |
| 689 | try renderToken(tree, ais, volatile_token, Space.Space); | |
| 690 | } | |
| 691 | return renderExpression(allocator, ais, tree, slice_type.rhs, space); | |
| 692 | }, | |
| 693 | ||
| 694 | .ArrayInitializer, .ArrayInitializerDot => { | |
| 695 | var rtoken: ast.TokenIndex = undefined; | |
| 696 | var exprs: []*ast.Node = undefined; | |
| 697 | const lhs: union(enum) { dot: ast.TokenIndex, node: *ast.Node } = switch (base.tag) { | |
| 698 | .ArrayInitializerDot => blk: { | |
| 699 | const casted = @fieldParentPtr(ast.Node.ArrayInitializerDot, "base", base); | |
| 700 | rtoken = casted.rtoken; | |
| 701 | exprs = casted.list(); | |
| 702 | break :blk .{ .dot = casted.dot }; | |
| 703 | }, | |
| 704 | .ArrayInitializer => blk: { | |
| 705 | const casted = @fieldParentPtr(ast.Node.ArrayInitializer, "base", base); | |
| 706 | rtoken = casted.rtoken; | |
| 707 | exprs = casted.list(); | |
| 708 | break :blk .{ .node = casted.lhs }; | |
| 709 | }, | |
| 710 | else => unreachable, | |
| 711 | }; | |
| 712 | ||
| 713 | const lbrace = switch (lhs) { | |
| 714 | .dot => |dot| tree.nextToken(dot), | |
| 715 | .node => |node| tree.nextToken(node.lastToken()), | |
| 716 | }; | |
| 717 | ||
| 718 | switch (lhs) { | |
| 719 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), | |
| 720 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 721 | } | |
| 722 | ||
| 723 | if (exprs.len == 0) { | |
| 724 | try renderToken(tree, ais, lbrace, Space.None); | |
| 725 | return renderToken(tree, ais, rtoken, space); | |
| 726 | } | |
| 727 | ||
| 728 | if (exprs.len == 1 and exprs[0].tag != .MultilineStringLiteral and tree.token_ids[exprs[0].*.lastToken() + 1] == .RBrace) { | |
| 729 | const expr = exprs[0]; | |
| 730 | ||
| 731 | try renderToken(tree, ais, lbrace, Space.None); | |
| 732 | try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 733 | return renderToken(tree, ais, rtoken, space); | |
| 734 | } | |
| 735 | ||
| 736 | // scan to find row size | |
| 737 | if (rowSize(tree, exprs, rtoken) != null) { | |
| 738 | { | |
| 739 | ais.pushIndentNextLine(); | |
| 740 | defer ais.popIndent(); | |
| 741 | try renderToken(tree, ais, lbrace, Space.Newline); | |
| 742 | ||
| 743 | var expr_index: usize = 0; | |
| 744 | while (rowSize(tree, exprs[expr_index..], rtoken)) |row_size| { | |
| 745 | const row_exprs = exprs[expr_index..]; | |
| 746 | // A place to store the width of each expression and its column's maximum | |
| 747 | var widths = try allocator.alloc(usize, row_exprs.len + row_size); | |
| 748 | defer allocator.free(widths); | |
| 749 | mem.set(usize, widths, 0); | |
| 750 | ||
| 751 | var expr_newlines = try allocator.alloc(bool, row_exprs.len); | |
| 752 | defer allocator.free(expr_newlines); | |
| 753 | mem.set(bool, expr_newlines, false); | |
| 754 | ||
| 755 | var expr_widths = widths[0 .. widths.len - row_size]; | |
| 756 | var column_widths = widths[widths.len - row_size ..]; | |
| 757 | ||
| 758 | // Find next row with trailing comment (if any) to end the current section | |
| 759 | var section_end = sec_end: { | |
| 760 | var this_line_first_expr: usize = 0; | |
| 761 | var this_line_size = rowSize(tree, row_exprs, rtoken); | |
| 762 | for (row_exprs) |expr, i| { | |
| 763 | // Ignore comment on first line of this section | |
| 764 | if (i == 0 or tree.tokensOnSameLine(row_exprs[0].firstToken(), expr.lastToken())) continue; | |
| 765 | // Track start of line containing comment | |
| 766 | if (!tree.tokensOnSameLine(row_exprs[this_line_first_expr].firstToken(), expr.lastToken())) { | |
| 767 | this_line_first_expr = i; | |
| 768 | this_line_size = rowSize(tree, row_exprs[this_line_first_expr..], rtoken); | |
| 769 | } | |
| 770 | ||
| 771 | const maybe_comma = expr.lastToken() + 1; | |
| 772 | const maybe_comment = expr.lastToken() + 2; | |
| 773 | if (maybe_comment < tree.token_ids.len) { | |
| 774 | if (tree.token_ids[maybe_comma] == .Comma and | |
| 775 | tree.token_ids[maybe_comment] == .LineComment and | |
| 776 | tree.tokensOnSameLine(expr.lastToken(), maybe_comment)) | |
| 777 | { | |
| 778 | var comment_token_loc = tree.token_locs[maybe_comment]; | |
| 779 | const comment_is_empty = mem.trimRight(u8, tree.tokenSliceLoc(comment_token_loc), " ").len == 2; | |
| 780 | if (!comment_is_empty) { | |
| 781 | // Found row ending in comment | |
| 782 | break :sec_end i - this_line_size.? + 1; | |
| 783 | } | |
| 784 | } | |
| 785 | } | |
| 786 | } | |
| 787 | break :sec_end row_exprs.len; | |
| 788 | }; | |
| 789 | expr_index += section_end; | |
| 790 | ||
| 791 | const section_exprs = row_exprs[0..section_end]; | |
| 792 | ||
| 793 | // Null stream for counting the printed length of each expression | |
| 794 | var line_find_stream = std.io.findByteWriter('\n', std.io.null_writer); | |
| 795 | var counting_stream = std.io.countingWriter(line_find_stream.writer()); | |
| 796 | var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, counting_stream.writer()); | |
| 797 | ||
| 798 | // Calculate size of columns in current section | |
| 799 | var column_counter: usize = 0; | |
| 800 | var single_line = true; | |
| 801 | for (section_exprs) |expr, i| { | |
| 802 | if (i + 1 < section_exprs.len) { | |
| 803 | counting_stream.bytes_written = 0; | |
| 804 | line_find_stream.byte_found = false; | |
| 805 | try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); | |
| 806 | const width = @intCast(usize, counting_stream.bytes_written); | |
| 807 | expr_widths[i] = width; | |
| 808 | expr_newlines[i] = line_find_stream.byte_found; | |
| 809 | ||
| 810 | if (!line_find_stream.byte_found) { | |
| 811 | const column = column_counter % row_size; | |
| 812 | column_widths[column] = std.math.max(column_widths[column], width); | |
| 813 | ||
| 814 | const expr_last_token = expr.*.lastToken() + 1; | |
| 815 | const next_expr = section_exprs[i + 1]; | |
| 816 | const loc = tree.tokenLocation(tree.token_locs[expr_last_token].start, next_expr.*.firstToken()); | |
| 817 | ||
| 818 | column_counter += 1; | |
| 819 | ||
| 820 | if (loc.line != 0) single_line = false; | |
| 821 | } else { | |
| 822 | single_line = false; | |
| 823 | column_counter = 0; | |
| 824 | } | |
| 825 | } else { | |
| 826 | counting_stream.bytes_written = 0; | |
| 827 | try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); | |
| 828 | const width = @intCast(usize, counting_stream.bytes_written); | |
| 829 | expr_widths[i] = width; | |
| 830 | expr_newlines[i] = line_find_stream.byte_found; | |
| 831 | ||
| 832 | if (!line_find_stream.byte_found) { | |
| 833 | const column = column_counter % row_size; | |
| 834 | column_widths[column] = std.math.max(column_widths[column], width); | |
| 835 | } | |
| 836 | break; | |
| 837 | } | |
| 838 | } | |
| 839 | ||
| 840 | // Render exprs in current section | |
| 841 | column_counter = 0; | |
| 842 | var last_col_index: usize = row_size - 1; | |
| 843 | for (section_exprs) |expr, i| { | |
| 844 | if (i + 1 < section_exprs.len) { | |
| 845 | const next_expr = section_exprs[i + 1]; | |
| 846 | try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 847 | ||
| 848 | const comma = tree.nextToken(expr.*.lastToken()); | |
| 849 | ||
| 850 | if (column_counter != last_col_index) { | |
| 851 | if (!expr_newlines[i] and !expr_newlines[i + 1]) { | |
| 852 | // Neither the current or next expression is multiline | |
| 853 | try renderToken(tree, ais, comma, Space.Space); // , | |
| 854 | assert(column_widths[column_counter % row_size] >= expr_widths[i]); | |
| 855 | const padding = column_widths[column_counter % row_size] - expr_widths[i]; | |
| 856 | try ais.writer().writeByteNTimes(' ', padding); | |
| 857 | ||
| 858 | column_counter += 1; | |
| 859 | continue; | |
| 860 | } | |
| 861 | } | |
| 862 | if (single_line and row_size != 1) { | |
| 863 | try renderToken(tree, ais, comma, Space.Space); // , | |
| 864 | continue; | |
| 865 | } | |
| 866 | ||
| 867 | column_counter = 0; | |
| 868 | try renderToken(tree, ais, comma, Space.Newline); // , | |
| 869 | try renderExtraNewline(tree, ais, next_expr); | |
| 870 | } else { | |
| 871 | const maybe_comma = tree.nextToken(expr.*.lastToken()); | |
| 872 | if (tree.token_ids[maybe_comma] == .Comma) { | |
| 873 | try renderExpression(allocator, ais, tree, expr, Space.None); // , | |
| 874 | try renderToken(tree, ais, maybe_comma, Space.Newline); // , | |
| 875 | } else { | |
| 876 | try renderExpression(allocator, ais, tree, expr, Space.Comma); // , | |
| 877 | } | |
| 878 | } | |
| 879 | } | |
| 880 | ||
| 881 | if (expr_index == exprs.len) { | |
| 882 | break; | |
| 883 | } | |
| 884 | } | |
| 885 | } | |
| 886 | ||
| 887 | return renderToken(tree, ais, rtoken, space); | |
| 888 | } | |
| 889 | ||
| 890 | // Single line | |
| 891 | try renderToken(tree, ais, lbrace, Space.Space); | |
| 892 | for (exprs) |expr, i| { | |
| 893 | if (i + 1 < exprs.len) { | |
| 894 | const next_expr = exprs[i + 1]; | |
| 895 | try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 896 | const comma = tree.nextToken(expr.*.lastToken()); | |
| 897 | try renderToken(tree, ais, comma, Space.Space); // , | |
| 898 | } else { | |
| 899 | try renderExpression(allocator, ais, tree, expr, Space.Space); | |
| 900 | } | |
| 901 | } | |
| 902 | ||
| 903 | return renderToken(tree, ais, rtoken, space); | |
| 904 | }, | |
| 905 | ||
| 906 | .StructInitializer, .StructInitializerDot => { | |
| 907 | var rtoken: ast.TokenIndex = undefined; | |
| 908 | var field_inits: []*ast.Node = undefined; | |
| 909 | const lhs: union(enum) { dot: ast.TokenIndex, node: *ast.Node } = switch (base.tag) { | |
| 910 | .StructInitializerDot => blk: { | |
| 911 | const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base); | |
| 912 | rtoken = casted.rtoken; | |
| 913 | field_inits = casted.list(); | |
| 914 | break :blk .{ .dot = casted.dot }; | |
| 915 | }, | |
| 916 | .StructInitializer => blk: { | |
| 917 | const casted = @fieldParentPtr(ast.Node.StructInitializer, "base", base); | |
| 918 | rtoken = casted.rtoken; | |
| 919 | field_inits = casted.list(); | |
| 920 | break :blk .{ .node = casted.lhs }; | |
| 921 | }, | |
| 922 | else => unreachable, | |
| 923 | }; | |
| 924 | ||
| 925 | const lbrace = switch (lhs) { | |
| 926 | .dot => |dot| tree.nextToken(dot), | |
| 927 | .node => |node| tree.nextToken(node.lastToken()), | |
| 928 | }; | |
| 929 | ||
| 930 | if (field_inits.len == 0) { | |
| 931 | switch (lhs) { | |
| 932 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), | |
| 933 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 934 | } | |
| 935 | ||
| 936 | { | |
| 937 | ais.pushIndentNextLine(); | |
| 938 | defer ais.popIndent(); | |
| 939 | try renderToken(tree, ais, lbrace, Space.None); | |
| 940 | } | |
| 941 | ||
| 942 | return renderToken(tree, ais, rtoken, space); | |
| 943 | } | |
| 944 | ||
| 945 | const src_has_trailing_comma = blk: { | |
| 946 | const maybe_comma = tree.prevToken(rtoken); | |
| 947 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 948 | }; | |
| 949 | ||
| 950 | const src_same_line = blk: { | |
| 951 | const loc = tree.tokenLocation(tree.token_locs[lbrace].end, rtoken); | |
| 952 | break :blk loc.line == 0; | |
| 953 | }; | |
| 954 | ||
| 955 | const expr_outputs_one_line = blk: { | |
| 956 | // render field expressions until a LF is found | |
| 957 | for (field_inits) |field_init| { | |
| 958 | var find_stream = std.io.findByteWriter('\n', std.io.null_writer); | |
| 959 | var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, find_stream.writer()); | |
| 960 | ||
| 961 | try renderExpression(allocator, &auto_indenting_stream, tree, field_init, Space.None); | |
| 962 | if (find_stream.byte_found) break :blk false; | |
| 963 | } | |
| 964 | break :blk true; | |
| 965 | }; | |
| 966 | ||
| 967 | if (field_inits.len == 1) blk: { | |
| 968 | if (field_inits[0].cast(ast.Node.FieldInitializer)) |field_init| { | |
| 969 | switch (field_init.expr.tag) { | |
| 970 | .StructInitializer, | |
| 971 | .StructInitializerDot, | |
| 972 | => break :blk, | |
| 973 | else => {}, | |
| 974 | } | |
| 975 | } | |
| 976 | ||
| 977 | // if the expression outputs to multiline, make this struct multiline | |
| 978 | if (!expr_outputs_one_line or src_has_trailing_comma) { | |
| 979 | break :blk; | |
| 980 | } | |
| 981 | ||
| 982 | switch (lhs) { | |
| 983 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), | |
| 984 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 985 | } | |
| 986 | try renderToken(tree, ais, lbrace, Space.Space); | |
| 987 | try renderExpression(allocator, ais, tree, field_inits[0], Space.Space); | |
| 988 | return renderToken(tree, ais, rtoken, space); | |
| 989 | } | |
| 990 | ||
| 991 | if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) { | |
| 992 | // render all on one line, no trailing comma | |
| 993 | switch (lhs) { | |
| 994 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), | |
| 995 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 996 | } | |
| 997 | try renderToken(tree, ais, lbrace, Space.Space); | |
| 998 | ||
| 999 | for (field_inits) |field_init, i| { | |
| 1000 | if (i + 1 < field_inits.len) { | |
| 1001 | try renderExpression(allocator, ais, tree, field_init, Space.None); | |
| 1002 | ||
| 1003 | const comma = tree.nextToken(field_init.lastToken()); | |
| 1004 | try renderToken(tree, ais, comma, Space.Space); | |
| 1005 | } else { | |
| 1006 | try renderExpression(allocator, ais, tree, field_init, Space.Space); | |
| 1007 | } | |
| 1008 | } | |
| 1009 | ||
| 1010 | return renderToken(tree, ais, rtoken, space); | |
| 1011 | } | |
| 1012 | ||
| 1013 | { | |
| 1014 | switch (lhs) { | |
| 1015 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), | |
| 1016 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 1017 | } | |
| 1018 | ||
| 1019 | ais.pushIndentNextLine(); | |
| 1020 | defer ais.popIndent(); | |
| 1021 | ||
| 1022 | try renderToken(tree, ais, lbrace, Space.Newline); | |
| 1023 | ||
| 1024 | for (field_inits) |field_init, i| { | |
| 1025 | if (i + 1 < field_inits.len) { | |
| 1026 | const next_field_init = field_inits[i + 1]; | |
| 1027 | try renderExpression(allocator, ais, tree, field_init, Space.None); | |
| 1028 | ||
| 1029 | const comma = tree.nextToken(field_init.lastToken()); | |
| 1030 | try renderToken(tree, ais, comma, Space.Newline); | |
| 1031 | ||
| 1032 | try renderExtraNewline(tree, ais, next_field_init); | |
| 1033 | } else { | |
| 1034 | try renderExpression(allocator, ais, tree, field_init, Space.Comma); | |
| 1035 | } | |
| 1036 | } | |
| 1037 | } | |
| 1038 | ||
| 1039 | return renderToken(tree, ais, rtoken, space); | |
| 1040 | }, | |
| 1041 | ||
| 1042 | .Call => { | |
| 1043 | const call = @fieldParentPtr(ast.Node.Call, "base", base); | |
| 1044 | if (call.async_token) |async_token| { | |
| 1045 | try renderToken(tree, ais, async_token, Space.Space); | |
| 1046 | } | |
| 1047 | ||
| 1048 | try renderExpression(allocator, ais, tree, call.lhs, Space.None); | |
| 1049 | ||
| 1050 | const lparen = tree.nextToken(call.lhs.lastToken()); | |
| 1051 | ||
| 1052 | if (call.params_len == 0) { | |
| 1053 | try renderToken(tree, ais, lparen, Space.None); | |
| 1054 | return renderToken(tree, ais, call.rtoken, space); | |
| 1055 | } | |
| 1056 | ||
| 1057 | const src_has_trailing_comma = blk: { | |
| 1058 | const maybe_comma = tree.prevToken(call.rtoken); | |
| 1059 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 1060 | }; | |
| 1061 | ||
| 1062 | if (src_has_trailing_comma) { | |
| 1063 | { | |
| 1064 | ais.pushIndent(); | |
| 1065 | defer ais.popIndent(); | |
| 1066 | ||
| 1067 | try renderToken(tree, ais, lparen, Space.Newline); // ( | |
| 1068 | const params = call.params(); | |
| 1069 | for (params) |param_node, i| { | |
| 1070 | if (i + 1 < params.len) { | |
| 1071 | const next_node = params[i + 1]; | |
| 1072 | try renderExpression(allocator, ais, tree, param_node, Space.None); | |
| 1073 | ||
| 1074 | // Unindent the comma for multiline string literals | |
| 1075 | const maybe_multiline_string = param_node.firstToken(); | |
| 1076 | const is_multiline_string = tree.token_ids[maybe_multiline_string] == .MultilineStringLiteralLine; | |
| 1077 | if (is_multiline_string) ais.popIndent(); | |
| 1078 | defer if (is_multiline_string) ais.pushIndent(); | |
| 1079 | ||
| 1080 | const comma = tree.nextToken(param_node.lastToken()); | |
| 1081 | try renderToken(tree, ais, comma, Space.Newline); // , | |
| 1082 | try renderExtraNewline(tree, ais, next_node); | |
| 1083 | } else { | |
| 1084 | try renderExpression(allocator, ais, tree, param_node, Space.Comma); | |
| 1085 | } | |
| 1086 | } | |
| 1087 | } | |
| 1088 | return renderToken(tree, ais, call.rtoken, space); | |
| 1089 | } | |
| 1090 | ||
| 1091 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1092 | ||
| 1093 | const params = call.params(); | |
| 1094 | for (params) |param_node, i| { | |
| 1095 | const maybe_comment = param_node.firstToken() - 1; | |
| 1096 | const maybe_multiline_string = param_node.firstToken(); | |
| 1097 | if (tree.token_ids[maybe_multiline_string] == .MultilineStringLiteralLine or tree.token_ids[maybe_comment] == .LineComment) { | |
| 1098 | ais.pushIndentOneShot(); | |
| 1099 | } | |
| 1100 | ||
| 1101 | try renderExpression(allocator, ais, tree, param_node, Space.None); | |
| 1102 | ||
| 1103 | if (i + 1 < params.len) { | |
| 1104 | const comma = tree.nextToken(param_node.lastToken()); | |
| 1105 | try renderToken(tree, ais, comma, Space.Space); | |
| 1106 | } | |
| 1107 | } | |
| 1108 | return renderToken(tree, ais, call.rtoken, space); // ) | |
| 1109 | }, | |
| 1110 | ||
| 1111 | .ArrayAccess => { | |
| 1112 | const suffix_op = base.castTag(.ArrayAccess).?; | |
| 1113 | ||
| 1114 | const lbracket = tree.nextToken(suffix_op.lhs.lastToken()); | |
| 1115 | const rbracket = tree.nextToken(suffix_op.index_expr.lastToken()); | |
| 1116 | ||
| 1117 | try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1118 | try renderToken(tree, ais, lbracket, Space.None); // [ | |
| 1119 | ||
| 1120 | const starts_with_comment = tree.token_ids[lbracket + 1] == .LineComment; | |
| 1121 | const ends_with_comment = tree.token_ids[rbracket - 1] == .LineComment; | |
| 1122 | { | |
| 1123 | const new_space = if (ends_with_comment) Space.Newline else Space.None; | |
| 1124 | ||
| 1125 | ais.pushIndent(); | |
| 1126 | defer ais.popIndent(); | |
| 1127 | try renderExpression(allocator, ais, tree, suffix_op.index_expr, new_space); | |
| 1128 | } | |
| 1129 | if (starts_with_comment) try ais.maybeInsertNewline(); | |
| 1130 | return renderToken(tree, ais, rbracket, space); // ] | |
| 1131 | }, | |
| 1132 | ||
| 1133 | .Slice => { | |
| 1134 | const suffix_op = base.castTag(.Slice).?; | |
| 1135 | try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1136 | ||
| 1137 | const lbracket = tree.prevToken(suffix_op.start.firstToken()); | |
| 1138 | const dotdot = tree.nextToken(suffix_op.start.lastToken()); | |
| 1139 | ||
| 1140 | const after_start_space_bool = nodeCausesSliceOpSpace(suffix_op.start) or | |
| 1141 | (if (suffix_op.end) |end| nodeCausesSliceOpSpace(end) else false); | |
| 1142 | const after_start_space = if (after_start_space_bool) Space.Space else Space.None; | |
| 1143 | const after_op_space = if (suffix_op.end != null) after_start_space else Space.None; | |
| 1144 | ||
| 1145 | try renderToken(tree, ais, lbracket, Space.None); // [ | |
| 1146 | try renderExpression(allocator, ais, tree, suffix_op.start, after_start_space); | |
| 1147 | try renderToken(tree, ais, dotdot, after_op_space); // .. | |
| 1148 | if (suffix_op.end) |end| { | |
| 1149 | const after_end_space = if (suffix_op.sentinel != null) Space.Space else Space.None; | |
| 1150 | try renderExpression(allocator, ais, tree, end, after_end_space); | |
| 1151 | } | |
| 1152 | if (suffix_op.sentinel) |sentinel| { | |
| 1153 | const colon = tree.prevToken(sentinel.firstToken()); | |
| 1154 | try renderToken(tree, ais, colon, Space.None); // : | |
| 1155 | try renderExpression(allocator, ais, tree, sentinel, Space.None); | |
| 1156 | } | |
| 1157 | return renderToken(tree, ais, suffix_op.rtoken, space); // ] | |
| 1158 | }, | |
| 1159 | ||
| 1160 | .Deref => { | |
| 1161 | const suffix_op = base.castTag(.Deref).?; | |
| 1162 | ||
| 1163 | try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1164 | return renderToken(tree, ais, suffix_op.rtoken, space); // .* | |
| 1165 | }, | |
| 1166 | .UnwrapOptional => { | |
| 1167 | const suffix_op = base.castTag(.UnwrapOptional).?; | |
| 1168 | ||
| 1169 | try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1170 | try renderToken(tree, ais, tree.prevToken(suffix_op.rtoken), Space.None); // . | |
| 1171 | return renderToken(tree, ais, suffix_op.rtoken, space); // ? | |
| 1172 | }, | |
| 1173 | ||
| 1174 | .Break => { | |
| 1175 | const flow_expr = base.castTag(.Break).?; | |
| 1176 | const maybe_rhs = flow_expr.getRHS(); | |
| 1177 | const maybe_label = flow_expr.getLabel(); | |
| 1178 | ||
| 1179 | if (maybe_label == null and maybe_rhs == null) { | |
| 1180 | return renderToken(tree, ais, flow_expr.ltoken, space); // break | |
| 1181 | } | |
| 1182 | ||
| 1183 | try renderToken(tree, ais, flow_expr.ltoken, Space.Space); // break | |
| 1184 | if (maybe_label) |label| { | |
| 1185 | const colon = tree.nextToken(flow_expr.ltoken); | |
| 1186 | try renderToken(tree, ais, colon, Space.None); // : | |
| 1187 | ||
| 1188 | if (maybe_rhs == null) { | |
| 1189 | return renderToken(tree, ais, label, space); // label | |
| 1190 | } | |
| 1191 | try renderToken(tree, ais, label, Space.Space); // label | |
| 1192 | } | |
| 1193 | return renderExpression(allocator, ais, tree, maybe_rhs.?, space); | |
| 1194 | }, | |
| 1195 | ||
| 1196 | .Continue => { | |
| 1197 | const flow_expr = base.castTag(.Continue).?; | |
| 1198 | if (flow_expr.getLabel()) |label| { | |
| 1199 | try renderToken(tree, ais, flow_expr.ltoken, Space.Space); // continue | |
| 1200 | const colon = tree.nextToken(flow_expr.ltoken); | |
| 1201 | try renderToken(tree, ais, colon, Space.None); // : | |
| 1202 | return renderToken(tree, ais, label, space); // label | |
| 1203 | } else { | |
| 1204 | return renderToken(tree, ais, flow_expr.ltoken, space); // continue | |
| 1205 | } | |
| 1206 | }, | |
| 1207 | ||
| 1208 | .Return => { | |
| 1209 | const flow_expr = base.castTag(.Return).?; | |
| 1210 | if (flow_expr.getRHS()) |rhs| { | |
| 1211 | try renderToken(tree, ais, flow_expr.ltoken, Space.Space); | |
| 1212 | return renderExpression(allocator, ais, tree, rhs, space); | |
| 1213 | } else { | |
| 1214 | return renderToken(tree, ais, flow_expr.ltoken, space); | |
| 1215 | } | |
| 1216 | }, | |
| 1217 | ||
| 1218 | .Payload => { | |
| 1219 | const payload = @fieldParentPtr(ast.Node.Payload, "base", base); | |
| 1220 | ||
| 1221 | try renderToken(tree, ais, payload.lpipe, Space.None); | |
| 1222 | try renderExpression(allocator, ais, tree, payload.error_symbol, Space.None); | |
| 1223 | return renderToken(tree, ais, payload.rpipe, space); | |
| 1224 | }, | |
| 1225 | ||
| 1226 | .PointerPayload => { | |
| 1227 | const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base); | |
| 1228 | ||
| 1229 | try renderToken(tree, ais, payload.lpipe, Space.None); | |
| 1230 | if (payload.ptr_token) |ptr_token| { | |
| 1231 | try renderToken(tree, ais, ptr_token, Space.None); | |
| 1232 | } | |
| 1233 | try renderExpression(allocator, ais, tree, payload.value_symbol, Space.None); | |
| 1234 | return renderToken(tree, ais, payload.rpipe, space); | |
| 1235 | }, | |
| 1236 | ||
| 1237 | .PointerIndexPayload => { | |
| 1238 | const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base); | |
| 1239 | ||
| 1240 | try renderToken(tree, ais, payload.lpipe, Space.None); | |
| 1241 | if (payload.ptr_token) |ptr_token| { | |
| 1242 | try renderToken(tree, ais, ptr_token, Space.None); | |
| 1243 | } | |
| 1244 | try renderExpression(allocator, ais, tree, payload.value_symbol, Space.None); | |
| 1245 | ||
| 1246 | if (payload.index_symbol) |index_symbol| { | |
| 1247 | const comma = tree.nextToken(payload.value_symbol.lastToken()); | |
| 1248 | ||
| 1249 | try renderToken(tree, ais, comma, Space.Space); | |
| 1250 | try renderExpression(allocator, ais, tree, index_symbol, Space.None); | |
| 1251 | } | |
| 1252 | ||
| 1253 | return renderToken(tree, ais, payload.rpipe, space); | |
| 1254 | }, | |
| 1255 | ||
| 1256 | .GroupedExpression => { | |
| 1257 | const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base); | |
| 1258 | ||
| 1259 | try renderToken(tree, ais, grouped_expr.lparen, Space.None); | |
| 1260 | { | |
| 1261 | ais.pushIndentOneShot(); | |
| 1262 | try renderExpression(allocator, ais, tree, grouped_expr.expr, Space.None); | |
| 1263 | } | |
| 1264 | return renderToken(tree, ais, grouped_expr.rparen, space); | |
| 1265 | }, | |
| 1266 | ||
| 1267 | .FieldInitializer => { | |
| 1268 | const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base); | |
| 1269 | ||
| 1270 | try renderToken(tree, ais, field_init.period_token, Space.None); // . | |
| 1271 | try renderToken(tree, ais, field_init.name_token, Space.Space); // name | |
| 1272 | try renderToken(tree, ais, tree.nextToken(field_init.name_token), Space.Space); // = | |
| 1273 | return renderExpression(allocator, ais, tree, field_init.expr, space); | |
| 1274 | }, | |
| 1275 | ||
| 1276 | .ContainerDecl => { | |
| 1277 | const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base); | |
| 1278 | ||
| 1279 | if (container_decl.layout_token) |layout_token| { | |
| 1280 | try renderToken(tree, ais, layout_token, Space.Space); | |
| 1281 | } | |
| 1282 | ||
| 1283 | switch (container_decl.init_arg_expr) { | |
| 1284 | .None => { | |
| 1285 | try renderToken(tree, ais, container_decl.kind_token, Space.Space); // union | |
| 1286 | }, | |
| 1287 | .Enum => |enum_tag_type| { | |
| 1288 | try renderToken(tree, ais, container_decl.kind_token, Space.None); // union | |
| 1289 | ||
| 1290 | const lparen = tree.nextToken(container_decl.kind_token); | |
| 1291 | const enum_token = tree.nextToken(lparen); | |
| 1292 | ||
| 1293 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1294 | try renderToken(tree, ais, enum_token, Space.None); // enum | |
| 1295 | ||
| 1296 | if (enum_tag_type) |expr| { | |
| 1297 | try renderToken(tree, ais, tree.nextToken(enum_token), Space.None); // ( | |
| 1298 | try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 1299 | ||
| 1300 | const rparen = tree.nextToken(expr.lastToken()); | |
| 1301 | try renderToken(tree, ais, rparen, Space.None); // ) | |
| 1302 | try renderToken(tree, ais, tree.nextToken(rparen), Space.Space); // ) | |
| 1303 | } else { | |
| 1304 | try renderToken(tree, ais, tree.nextToken(enum_token), Space.Space); // ) | |
| 1305 | } | |
| 1306 | }, | |
| 1307 | .Type => |type_expr| { | |
| 1308 | try renderToken(tree, ais, container_decl.kind_token, Space.None); // union | |
| 1309 | ||
| 1310 | const lparen = tree.nextToken(container_decl.kind_token); | |
| 1311 | const rparen = tree.nextToken(type_expr.lastToken()); | |
| 1312 | ||
| 1313 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1314 | try renderExpression(allocator, ais, tree, type_expr, Space.None); | |
| 1315 | try renderToken(tree, ais, rparen, Space.Space); // ) | |
| 1316 | }, | |
| 1317 | } | |
| 1318 | ||
| 1319 | if (container_decl.fields_and_decls_len == 0) { | |
| 1320 | { | |
| 1321 | ais.pushIndentNextLine(); | |
| 1322 | defer ais.popIndent(); | |
| 1323 | try renderToken(tree, ais, container_decl.lbrace_token, Space.None); // { | |
| 1324 | } | |
| 1325 | return renderToken(tree, ais, container_decl.rbrace_token, space); // } | |
| 1326 | } | |
| 1327 | ||
| 1328 | const src_has_trailing_comma = blk: { | |
| 1329 | var maybe_comma = tree.prevToken(container_decl.lastToken()); | |
| 1330 | // Doc comments for a field may also appear after the comma, eg. | |
| 1331 | // field_name: T, // comment attached to field_name | |
| 1332 | if (tree.token_ids[maybe_comma] == .DocComment) | |
| 1333 | maybe_comma = tree.prevToken(maybe_comma); | |
| 1334 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 1335 | }; | |
| 1336 | ||
| 1337 | const fields_and_decls = container_decl.fieldsAndDecls(); | |
| 1338 | ||
| 1339 | // Check if the first declaration and the { are on the same line | |
| 1340 | const src_has_newline = !tree.tokensOnSameLine( | |
| 1341 | container_decl.lbrace_token, | |
| 1342 | fields_and_decls[0].firstToken(), | |
| 1343 | ); | |
| 1344 | ||
| 1345 | // We can only print all the elements in-line if all the | |
| 1346 | // declarations inside are fields | |
| 1347 | const src_has_only_fields = blk: { | |
| 1348 | for (fields_and_decls) |decl| { | |
| 1349 | if (decl.tag != .ContainerField) break :blk false; | |
| 1350 | } | |
| 1351 | break :blk true; | |
| 1352 | }; | |
| 1353 | ||
| 1354 | if (src_has_trailing_comma or !src_has_only_fields) { | |
| 1355 | // One declaration per line | |
| 1356 | ais.pushIndentNextLine(); | |
| 1357 | defer ais.popIndent(); | |
| 1358 | try renderToken(tree, ais, container_decl.lbrace_token, .Newline); // { | |
| 1359 | ||
| 1360 | for (fields_and_decls) |decl, i| { | |
| 1361 | try renderContainerDecl(allocator, ais, tree, decl, .Newline); | |
| 1362 | ||
| 1363 | if (i + 1 < fields_and_decls.len) { | |
| 1364 | try renderExtraNewline(tree, ais, fields_and_decls[i + 1]); | |
| 1365 | } | |
| 1366 | } | |
| 1367 | } else if (src_has_newline) { | |
| 1368 | // All the declarations on the same line, but place the items on | |
| 1369 | // their own line | |
| 1370 | try renderToken(tree, ais, container_decl.lbrace_token, .Newline); // { | |
| 1371 | ||
| 1372 | ais.pushIndent(); | |
| 1373 | defer ais.popIndent(); | |
| 1374 | ||
| 1375 | for (fields_and_decls) |decl, i| { | |
| 1376 | const space_after_decl: Space = if (i + 1 >= fields_and_decls.len) .Newline else .Space; | |
| 1377 | try renderContainerDecl(allocator, ais, tree, decl, space_after_decl); | |
| 1378 | } | |
| 1379 | } else { | |
| 1380 | // All the declarations on the same line | |
| 1381 | try renderToken(tree, ais, container_decl.lbrace_token, .Space); // { | |
| 1382 | ||
| 1383 | for (fields_and_decls) |decl| { | |
| 1384 | try renderContainerDecl(allocator, ais, tree, decl, .Space); | |
| 1385 | } | |
| 1386 | } | |
| 1387 | ||
| 1388 | return renderToken(tree, ais, container_decl.rbrace_token, space); // } | |
| 1389 | }, | |
| 1390 | ||
| 1391 | .ErrorSetDecl => { | |
| 1392 | const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base); | |
| 1393 | ||
| 1394 | const lbrace = tree.nextToken(err_set_decl.error_token); | |
| 1395 | ||
| 1396 | if (err_set_decl.decls_len == 0) { | |
| 1397 | try renderToken(tree, ais, err_set_decl.error_token, Space.None); | |
| 1398 | try renderToken(tree, ais, lbrace, Space.None); | |
| 1399 | return renderToken(tree, ais, err_set_decl.rbrace_token, space); | |
| 1400 | } | |
| 1401 | ||
| 1402 | if (err_set_decl.decls_len == 1) blk: { | |
| 1403 | const node = err_set_decl.decls()[0]; | |
| 1404 | ||
| 1405 | // if there are any doc comments or same line comments | |
| 1406 | // don't try to put it all on one line | |
| 1407 | if (node.cast(ast.Node.ErrorTag)) |tag| { | |
| 1408 | if (tag.doc_comments != null) break :blk; | |
| 1409 | } else { | |
| 1410 | break :blk; | |
| 1411 | } | |
| 1412 | ||
| 1413 | try renderToken(tree, ais, err_set_decl.error_token, Space.None); // error | |
| 1414 | try renderToken(tree, ais, lbrace, Space.None); // { | |
| 1415 | try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1416 | return renderToken(tree, ais, err_set_decl.rbrace_token, space); // } | |
| 1417 | } | |
| 1418 | ||
| 1419 | try renderToken(tree, ais, err_set_decl.error_token, Space.None); // error | |
| 1420 | ||
| 1421 | const src_has_trailing_comma = blk: { | |
| 1422 | const maybe_comma = tree.prevToken(err_set_decl.rbrace_token); | |
| 1423 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 1424 | }; | |
| 1425 | ||
| 1426 | if (src_has_trailing_comma) { | |
| 1427 | { | |
| 1428 | ais.pushIndent(); | |
| 1429 | defer ais.popIndent(); | |
| 1430 | ||
| 1431 | try renderToken(tree, ais, lbrace, Space.Newline); // { | |
| 1432 | const decls = err_set_decl.decls(); | |
| 1433 | for (decls) |node, i| { | |
| 1434 | if (i + 1 < decls.len) { | |
| 1435 | try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1436 | try renderToken(tree, ais, tree.nextToken(node.lastToken()), Space.Newline); // , | |
| 1437 | ||
| 1438 | try renderExtraNewline(tree, ais, decls[i + 1]); | |
| 1439 | } else { | |
| 1440 | try renderExpression(allocator, ais, tree, node, Space.Comma); | |
| 1441 | } | |
| 1442 | } | |
| 1443 | } | |
| 1444 | ||
| 1445 | return renderToken(tree, ais, err_set_decl.rbrace_token, space); // } | |
| 1446 | } else { | |
| 1447 | try renderToken(tree, ais, lbrace, Space.Space); // { | |
| 1448 | ||
| 1449 | const decls = err_set_decl.decls(); | |
| 1450 | for (decls) |node, i| { | |
| 1451 | if (i + 1 < decls.len) { | |
| 1452 | try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1453 | ||
| 1454 | const comma_token = tree.nextToken(node.lastToken()); | |
| 1455 | assert(tree.token_ids[comma_token] == .Comma); | |
| 1456 | try renderToken(tree, ais, comma_token, Space.Space); // , | |
| 1457 | try renderExtraNewline(tree, ais, decls[i + 1]); | |
| 1458 | } else { | |
| 1459 | try renderExpression(allocator, ais, tree, node, Space.Space); | |
| 1460 | } | |
| 1461 | } | |
| 1462 | ||
| 1463 | return renderToken(tree, ais, err_set_decl.rbrace_token, space); // } | |
| 1464 | } | |
| 1465 | }, | |
| 1466 | ||
| 1467 | .ErrorTag => { | |
| 1468 | const tag = @fieldParentPtr(ast.Node.ErrorTag, "base", base); | |
| 1469 | ||
| 1470 | try renderDocComments(tree, ais, tag, tag.doc_comments); | |
| 1471 | return renderToken(tree, ais, tag.name_token, space); // name | |
| 1472 | }, | |
| 1473 | ||
| 1474 | .MultilineStringLiteral => { | |
| 1475 | const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base); | |
| 1476 | ||
| 1477 | { | |
| 1478 | const locked_indents = ais.lockOneShotIndent(); | |
| 1479 | defer { | |
| 1480 | var i: u8 = 0; | |
| 1481 | while (i < locked_indents) : (i += 1) ais.popIndent(); | |
| 1482 | } | |
| 1483 | try ais.maybeInsertNewline(); | |
| 1484 | ||
| 1485 | for (multiline_str_literal.lines()) |t| try renderToken(tree, ais, t, Space.None); | |
| 1486 | } | |
| 1487 | }, | |
| 1488 | ||
| 1489 | .BuiltinCall => { | |
| 1490 | const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base); | |
| 1491 | ||
| 1492 | // TODO remove after 0.7.0 release | |
| 1493 | if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@OpaqueType")) | |
| 1494 | return ais.writer().writeAll("opaque {}"); | |
| 1495 | ||
| 1496 | // TODO remove after 0.7.0 release | |
| 1497 | { | |
| 1498 | const params = builtin_call.paramsConst(); | |
| 1499 | if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@Type") and | |
| 1500 | params.len == 1) | |
| 1501 | { | |
| 1502 | if (params[0].castTag(.EnumLiteral)) |enum_literal| | |
| 1503 | if (mem.eql(u8, tree.tokenSlice(enum_literal.name), "Opaque")) | |
| 1504 | return ais.writer().writeAll("opaque {}"); | |
| 1505 | } | |
| 1506 | } | |
| 1507 | ||
| 1508 | try renderToken(tree, ais, builtin_call.builtin_token, Space.None); // @name | |
| 1509 | ||
| 1510 | const src_params_trailing_comma = blk: { | |
| 1511 | if (builtin_call.params_len == 0) break :blk false; | |
| 1512 | const last_node = builtin_call.params()[builtin_call.params_len - 1]; | |
| 1513 | const maybe_comma = tree.nextToken(last_node.lastToken()); | |
| 1514 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 1515 | }; | |
| 1516 | ||
| 1517 | const lparen = tree.nextToken(builtin_call.builtin_token); | |
| 1518 | ||
| 1519 | if (!src_params_trailing_comma) { | |
| 1520 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1521 | ||
| 1522 | // render all on one line, no trailing comma | |
| 1523 | const params = builtin_call.params(); | |
| 1524 | for (params) |param_node, i| { | |
| 1525 | const maybe_comment = param_node.firstToken() - 1; | |
| 1526 | if (param_node.*.tag == .MultilineStringLiteral or tree.token_ids[maybe_comment] == .LineComment) { | |
| 1527 | ais.pushIndentOneShot(); | |
| 1528 | } | |
| 1529 | try renderExpression(allocator, ais, tree, param_node, Space.None); | |
| 1530 | ||
| 1531 | if (i + 1 < params.len) { | |
| 1532 | const comma_token = tree.nextToken(param_node.lastToken()); | |
| 1533 | try renderToken(tree, ais, comma_token, Space.Space); // , | |
| 1534 | } | |
| 1535 | } | |
| 1536 | } else { | |
| 1537 | // one param per line | |
| 1538 | ais.pushIndent(); | |
| 1539 | defer ais.popIndent(); | |
| 1540 | try renderToken(tree, ais, lparen, Space.Newline); // ( | |
| 1541 | ||
| 1542 | for (builtin_call.params()) |param_node| { | |
| 1543 | try renderExpression(allocator, ais, tree, param_node, Space.Comma); | |
| 1544 | } | |
| 1545 | } | |
| 1546 | ||
| 1547 | return renderToken(tree, ais, builtin_call.rparen_token, space); // ) | |
| 1548 | }, | |
| 1549 | ||
| 1550 | .FnProto => { | |
| 1551 | const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", base); | |
| 1552 | ||
| 1553 | if (fn_proto.getVisibToken()) |visib_token_index| { | |
| 1554 | const visib_token = tree.token_ids[visib_token_index]; | |
| 1555 | assert(visib_token == .Keyword_pub or visib_token == .Keyword_export); | |
| 1556 | ||
| 1557 | try renderToken(tree, ais, visib_token_index, Space.Space); // pub | |
| 1558 | } | |
| 1559 | ||
| 1560 | if (fn_proto.getExternExportInlineToken()) |extern_export_inline_token| { | |
| 1561 | if (fn_proto.getIsExternPrototype() == null) | |
| 1562 | try renderToken(tree, ais, extern_export_inline_token, Space.Space); // extern/export/inline | |
| 1563 | } | |
| 1564 | ||
| 1565 | if (fn_proto.getLibName()) |lib_name| { | |
| 1566 | try renderExpression(allocator, ais, tree, lib_name, Space.Space); | |
| 1567 | } | |
| 1568 | ||
| 1569 | const lparen = if (fn_proto.getNameToken()) |name_token| blk: { | |
| 1570 | try renderToken(tree, ais, fn_proto.fn_token, Space.Space); // fn | |
| 1571 | try renderToken(tree, ais, name_token, Space.None); // name | |
| 1572 | break :blk tree.nextToken(name_token); | |
| 1573 | } else blk: { | |
| 1574 | try renderToken(tree, ais, fn_proto.fn_token, Space.Space); // fn | |
| 1575 | break :blk tree.nextToken(fn_proto.fn_token); | |
| 1576 | }; | |
| 1577 | assert(tree.token_ids[lparen] == .LParen); | |
| 1578 | ||
| 1579 | const rparen = tree.prevToken( | |
| 1580 | // the first token for the annotation expressions is the left | |
| 1581 | // parenthesis, hence the need for two prevToken | |
| 1582 | if (fn_proto.getAlignExpr()) |align_expr| | |
| 1583 | tree.prevToken(tree.prevToken(align_expr.firstToken())) | |
| 1584 | else if (fn_proto.getSectionExpr()) |section_expr| | |
| 1585 | tree.prevToken(tree.prevToken(section_expr.firstToken())) | |
| 1586 | else if (fn_proto.getCallconvExpr()) |callconv_expr| | |
| 1587 | tree.prevToken(tree.prevToken(callconv_expr.firstToken())) | |
| 1588 | else switch (fn_proto.return_type) { | |
| 1589 | .Explicit => |node| node.firstToken(), | |
| 1590 | .InferErrorSet => |node| tree.prevToken(node.firstToken()), | |
| 1591 | .Invalid => unreachable, | |
| 1592 | }, | |
| 1593 | ); | |
| 1594 | assert(tree.token_ids[rparen] == .RParen); | |
| 1595 | ||
| 1596 | const src_params_trailing_comma = blk: { | |
| 1597 | const maybe_comma = tree.token_ids[rparen - 1]; | |
| 1598 | break :blk maybe_comma == .Comma or maybe_comma == .LineComment; | |
| 1599 | }; | |
| 1600 | ||
| 1601 | if (!src_params_trailing_comma) { | |
| 1602 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1603 | ||
| 1604 | // render all on one line, no trailing comma | |
| 1605 | for (fn_proto.params()) |param_decl, i| { | |
| 1606 | try renderParamDecl(allocator, ais, tree, param_decl, Space.None); | |
| 1607 | ||
| 1608 | if (i + 1 < fn_proto.params_len or fn_proto.getVarArgsToken() != null) { | |
| 1609 | const comma = tree.nextToken(param_decl.lastToken()); | |
| 1610 | try renderToken(tree, ais, comma, Space.Space); // , | |
| 1611 | } | |
| 1612 | } | |
| 1613 | if (fn_proto.getVarArgsToken()) |var_args_token| { | |
| 1614 | try renderToken(tree, ais, var_args_token, Space.None); | |
| 1615 | } | |
| 1616 | } else { | |
| 1617 | // one param per line | |
| 1618 | ais.pushIndent(); | |
| 1619 | defer ais.popIndent(); | |
| 1620 | try renderToken(tree, ais, lparen, Space.Newline); // ( | |
| 1621 | ||
| 1622 | for (fn_proto.params()) |param_decl| { | |
| 1623 | try renderParamDecl(allocator, ais, tree, param_decl, Space.Comma); | |
| 1624 | } | |
| 1625 | if (fn_proto.getVarArgsToken()) |var_args_token| { | |
| 1626 | try renderToken(tree, ais, var_args_token, Space.Comma); | |
| 1627 | } | |
| 1628 | } | |
| 1629 | ||
| 1630 | try renderToken(tree, ais, rparen, Space.Space); // ) | |
| 1631 | ||
| 1632 | if (fn_proto.getAlignExpr()) |align_expr| { | |
| 1633 | const align_rparen = tree.nextToken(align_expr.lastToken()); | |
| 1634 | const align_lparen = tree.prevToken(align_expr.firstToken()); | |
| 1635 | const align_kw = tree.prevToken(align_lparen); | |
| 1636 | ||
| 1637 | try renderToken(tree, ais, align_kw, Space.None); // align | |
| 1638 | try renderToken(tree, ais, align_lparen, Space.None); // ( | |
| 1639 | try renderExpression(allocator, ais, tree, align_expr, Space.None); | |
| 1640 | try renderToken(tree, ais, align_rparen, Space.Space); // ) | |
| 1641 | } | |
| 1642 | ||
| 1643 | if (fn_proto.getSectionExpr()) |section_expr| { | |
| 1644 | const section_rparen = tree.nextToken(section_expr.lastToken()); | |
| 1645 | const section_lparen = tree.prevToken(section_expr.firstToken()); | |
| 1646 | const section_kw = tree.prevToken(section_lparen); | |
| 1647 | ||
| 1648 | try renderToken(tree, ais, section_kw, Space.None); // section | |
| 1649 | try renderToken(tree, ais, section_lparen, Space.None); // ( | |
| 1650 | try renderExpression(allocator, ais, tree, section_expr, Space.None); | |
| 1651 | try renderToken(tree, ais, section_rparen, Space.Space); // ) | |
| 1652 | } | |
| 1653 | ||
| 1654 | if (fn_proto.getCallconvExpr()) |callconv_expr| { | |
| 1655 | const callconv_rparen = tree.nextToken(callconv_expr.lastToken()); | |
| 1656 | const callconv_lparen = tree.prevToken(callconv_expr.firstToken()); | |
| 1657 | const callconv_kw = tree.prevToken(callconv_lparen); | |
| 1658 | ||
| 1659 | try renderToken(tree, ais, callconv_kw, Space.None); // callconv | |
| 1660 | try renderToken(tree, ais, callconv_lparen, Space.None); // ( | |
| 1661 | try renderExpression(allocator, ais, tree, callconv_expr, Space.None); | |
| 1662 | try renderToken(tree, ais, callconv_rparen, Space.Space); // ) | |
| 1663 | } else if (fn_proto.getIsExternPrototype() != null) { | |
| 1664 | try ais.writer().writeAll("callconv(.C) "); | |
| 1665 | } else if (fn_proto.getIsAsync() != null) { | |
| 1666 | try ais.writer().writeAll("callconv(.Async) "); | |
| 1667 | } | |
| 1668 | ||
| 1669 | switch (fn_proto.return_type) { | |
| 1670 | .Explicit => |node| { | |
| 1671 | return renderExpression(allocator, ais, tree, node, space); | |
| 1672 | }, | |
| 1673 | .InferErrorSet => |node| { | |
| 1674 | try renderToken(tree, ais, tree.prevToken(node.firstToken()), Space.None); // ! | |
| 1675 | return renderExpression(allocator, ais, tree, node, space); | |
| 1676 | }, | |
| 1677 | .Invalid => unreachable, | |
| 1678 | } | |
| 1679 | }, | |
| 1680 | ||
| 1681 | .AnyFrameType => { | |
| 1682 | const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base); | |
| 1683 | ||
| 1684 | if (anyframe_type.result) |result| { | |
| 1685 | try renderToken(tree, ais, anyframe_type.anyframe_token, Space.None); // anyframe | |
| 1686 | try renderToken(tree, ais, result.arrow_token, Space.None); // -> | |
| 1687 | return renderExpression(allocator, ais, tree, result.return_type, space); | |
| 1688 | } else { | |
| 1689 | return renderToken(tree, ais, anyframe_type.anyframe_token, space); // anyframe | |
| 1690 | } | |
| 1691 | }, | |
| 1692 | ||
| 1693 | .DocComment => unreachable, // doc comments are attached to nodes | |
| 1694 | ||
| 1695 | .Switch => { | |
| 1696 | const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base); | |
| 1697 | ||
| 1698 | try renderToken(tree, ais, switch_node.switch_token, Space.Space); // switch | |
| 1699 | try renderToken(tree, ais, tree.nextToken(switch_node.switch_token), Space.None); // ( | |
| 1700 | ||
| 1701 | const rparen = tree.nextToken(switch_node.expr.lastToken()); | |
| 1702 | const lbrace = tree.nextToken(rparen); | |
| 1703 | ||
| 1704 | if (switch_node.cases_len == 0) { | |
| 1705 | try renderExpression(allocator, ais, tree, switch_node.expr, Space.None); | |
| 1706 | try renderToken(tree, ais, rparen, Space.Space); // ) | |
| 1707 | try renderToken(tree, ais, lbrace, Space.None); // { | |
| 1708 | return renderToken(tree, ais, switch_node.rbrace, space); // } | |
| 1709 | } | |
| 1710 | ||
| 1711 | try renderExpression(allocator, ais, tree, switch_node.expr, Space.None); | |
| 1712 | try renderToken(tree, ais, rparen, Space.Space); // ) | |
| 1713 | ||
| 1714 | { | |
| 1715 | ais.pushIndentNextLine(); | |
| 1716 | defer ais.popIndent(); | |
| 1717 | try renderToken(tree, ais, lbrace, Space.Newline); // { | |
| 1718 | ||
| 1719 | const cases = switch_node.cases(); | |
| 1720 | for (cases) |node, i| { | |
| 1721 | try renderExpression(allocator, ais, tree, node, Space.Comma); | |
| 1722 | ||
| 1723 | if (i + 1 < cases.len) { | |
| 1724 | try renderExtraNewline(tree, ais, cases[i + 1]); | |
| 1725 | } | |
| 1726 | } | |
| 1727 | } | |
| 1728 | ||
| 1729 | return renderToken(tree, ais, switch_node.rbrace, space); // } | |
| 1730 | }, | |
| 1731 | ||
| 1732 | .SwitchCase => { | |
| 1733 | const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base); | |
| 1734 | ||
| 1735 | assert(switch_case.items_len != 0); | |
| 1736 | const src_has_trailing_comma = blk: { | |
| 1737 | const last_node = switch_case.items()[switch_case.items_len - 1]; | |
| 1738 | const maybe_comma = tree.nextToken(last_node.lastToken()); | |
| 1739 | break :blk tree.token_ids[maybe_comma] == .Comma; | |
| 1740 | }; | |
| 1741 | ||
| 1742 | if (switch_case.items_len == 1 or !src_has_trailing_comma) { | |
| 1743 | const items = switch_case.items(); | |
| 1744 | for (items) |node, i| { | |
| 1745 | if (i + 1 < items.len) { | |
| 1746 | try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1747 | ||
| 1748 | const comma_token = tree.nextToken(node.lastToken()); | |
| 1749 | try renderToken(tree, ais, comma_token, Space.Space); // , | |
| 1750 | try renderExtraNewline(tree, ais, items[i + 1]); | |
| 1751 | } else { | |
| 1752 | try renderExpression(allocator, ais, tree, node, Space.Space); | |
| 1753 | } | |
| 1754 | } | |
| 1755 | } else { | |
| 1756 | const items = switch_case.items(); | |
| 1757 | for (items) |node, i| { | |
| 1758 | if (i + 1 < items.len) { | |
| 1759 | try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1760 | ||
| 1761 | const comma_token = tree.nextToken(node.lastToken()); | |
| 1762 | try renderToken(tree, ais, comma_token, Space.Newline); // , | |
| 1763 | try renderExtraNewline(tree, ais, items[i + 1]); | |
| 1764 | } else { | |
| 1765 | try renderExpression(allocator, ais, tree, node, Space.Comma); | |
| 1766 | } | |
| 1767 | } | |
| 1768 | } | |
| 1769 | ||
| 1770 | try renderToken(tree, ais, switch_case.arrow_token, Space.Space); // => | |
| 1771 | ||
| 1772 | if (switch_case.payload) |payload| { | |
| 1773 | try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 1774 | } | |
| 1775 | ||
| 1776 | return renderExpression(allocator, ais, tree, switch_case.expr, space); | |
| 1777 | }, | |
| 1778 | .SwitchElse => { | |
| 1779 | const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base); | |
| 1780 | return renderToken(tree, ais, switch_else.token, space); | |
| 1781 | }, | |
| 1782 | .Else => { | |
| 1783 | const else_node = @fieldParentPtr(ast.Node.Else, "base", base); | |
| 1784 | ||
| 1785 | const body_is_block = nodeIsBlock(else_node.body); | |
| 1786 | const same_line = body_is_block or tree.tokensOnSameLine(else_node.else_token, else_node.body.lastToken()); | |
| 1787 | ||
| 1788 | const after_else_space = if (same_line or else_node.payload != null) Space.Space else Space.Newline; | |
| 1789 | try renderToken(tree, ais, else_node.else_token, after_else_space); | |
| 1790 | ||
| 1791 | if (else_node.payload) |payload| { | |
| 1792 | const payload_space = if (same_line) Space.Space else Space.Newline; | |
| 1793 | try renderExpression(allocator, ais, tree, payload, payload_space); | |
| 1794 | } | |
| 1795 | ||
| 1796 | if (same_line) { | |
| 1797 | return renderExpression(allocator, ais, tree, else_node.body, space); | |
| 1798 | } else { | |
| 1799 | ais.pushIndent(); | |
| 1800 | defer ais.popIndent(); | |
| 1801 | return renderExpression(allocator, ais, tree, else_node.body, space); | |
| 1802 | } | |
| 1803 | }, | |
| 1804 | ||
| 1805 | .While => { | |
| 1806 | const while_node = @fieldParentPtr(ast.Node.While, "base", base); | |
| 1807 | ||
| 1808 | if (while_node.label) |label| { | |
| 1809 | try renderToken(tree, ais, label, Space.None); // label | |
| 1810 | try renderToken(tree, ais, tree.nextToken(label), Space.Space); // : | |
| 1811 | } | |
| 1812 | ||
| 1813 | if (while_node.inline_token) |inline_token| { | |
| 1814 | try renderToken(tree, ais, inline_token, Space.Space); // inline | |
| 1815 | } | |
| 1816 | ||
| 1817 | try renderToken(tree, ais, while_node.while_token, Space.Space); // while | |
| 1818 | try renderToken(tree, ais, tree.nextToken(while_node.while_token), Space.None); // ( | |
| 1819 | try renderExpression(allocator, ais, tree, while_node.condition, Space.None); | |
| 1820 | ||
| 1821 | const cond_rparen = tree.nextToken(while_node.condition.lastToken()); | |
| 1822 | ||
| 1823 | const body_is_block = nodeIsBlock(while_node.body); | |
| 1824 | ||
| 1825 | var block_start_space: Space = undefined; | |
| 1826 | var after_body_space: Space = undefined; | |
| 1827 | ||
| 1828 | if (body_is_block) { | |
| 1829 | block_start_space = Space.BlockStart; | |
| 1830 | after_body_space = if (while_node.@"else" == null) space else Space.SpaceOrOutdent; | |
| 1831 | } else if (tree.tokensOnSameLine(cond_rparen, while_node.body.lastToken())) { | |
| 1832 | block_start_space = Space.Space; | |
| 1833 | after_body_space = if (while_node.@"else" == null) space else Space.Space; | |
| 1834 | } else { | |
| 1835 | block_start_space = Space.Newline; | |
| 1836 | after_body_space = if (while_node.@"else" == null) space else Space.Newline; | |
| 1837 | } | |
| 1838 | ||
| 1839 | { | |
| 1840 | const rparen_space = if (while_node.payload != null or while_node.continue_expr != null) Space.Space else block_start_space; | |
| 1841 | try renderToken(tree, ais, cond_rparen, rparen_space); // ) | |
| 1842 | } | |
| 1843 | ||
| 1844 | if (while_node.payload) |payload| { | |
| 1845 | const payload_space = if (while_node.continue_expr != null) Space.Space else block_start_space; | |
| 1846 | try renderExpression(allocator, ais, tree, payload, payload_space); | |
| 1847 | } | |
| 1848 | ||
| 1849 | if (while_node.continue_expr) |continue_expr| { | |
| 1850 | const rparen = tree.nextToken(continue_expr.lastToken()); | |
| 1851 | const lparen = tree.prevToken(continue_expr.firstToken()); | |
| 1852 | const colon = tree.prevToken(lparen); | |
| 1853 | ||
| 1854 | try renderToken(tree, ais, colon, Space.Space); // : | |
| 1855 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1856 | ||
| 1857 | try renderExpression(allocator, ais, tree, continue_expr, Space.None); | |
| 1858 | ||
| 1859 | try renderToken(tree, ais, rparen, block_start_space); // ) | |
| 1860 | } | |
| 1861 | ||
| 1862 | { | |
| 1863 | if (!body_is_block) ais.pushIndent(); | |
| 1864 | defer if (!body_is_block) ais.popIndent(); | |
| 1865 | try renderExpression(allocator, ais, tree, while_node.body, after_body_space); | |
| 1866 | } | |
| 25 | /// Returns whether anything changed. | |
| 26 | /// `gpa` is used for allocating extra stack memory if needed, because | |
| 27 | /// this function utilizes recursion. | |
| 28 | pub fn render(gpa: *mem.Allocator, writer: Writer, tree: ast.Tree) Error!void { | |
| 29 | assert(tree.errors.len == 0); // cannot render an invalid tree | |
| 30 | var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, writer); | |
| 31 | try renderRoot(&auto_indenting_stream, tree); | |
| 32 | } | |
| 1867 | 33 | |
| 1868 | if (while_node.@"else") |@"else"| { | |
| 1869 | return renderExpression(allocator, ais, tree, &@"else".base, space); | |
| 34 | /// Assumes there are no tokens in between start and end. | |
| 35 | fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize, prefix: []const u8) Error!usize { | |
| 36 | var index: usize = start; | |
| 37 | var count: usize = 0; | |
| 38 | while (true) { | |
| 39 | // Scan forward to the next line comment, counting newlines. | |
| 40 | const comment_start = mem.indexOf(u8, tree.source[index..end], "//") orelse return count; | |
| 41 | const newline = mem.indexOfScalar(u8, tree.source[comment_start..end], '\n').?; | |
| 42 | const untrimmed_comment = tree.source[comment_start..][0..newline]; | |
| 43 | const trimmed_comment = mem.trimRight(u8, untrimmed_comment, " \r\t"); | |
| 44 | if (count == 0) { | |
| 45 | count += 1; | |
| 46 | try ais.writer().writeAll(prefix); | |
| 47 | } else { | |
| 48 | // If another newline occurs between prev comment and this one | |
| 49 | // we honor it, but not any additional ones. | |
| 50 | if (mem.indexOfScalar(u8, tree.source[index..comment_start], '\n') != null) { | |
| 51 | try ais.insertNewline(); | |
| 1870 | 52 | } |
| 1871 | }, | |
| 53 | } | |
| 54 | try ais.writer().print("{s}\n", .{trimmed_comment}); | |
| 55 | index += comment_start + newline; | |
| 56 | } | |
| 57 | } | |
| 1872 | 58 | |
| 1873 | .For => { | |
| 1874 | const for_node = @fieldParentPtr(ast.Node.For, "base", base); | |
| 59 | fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void { | |
| 60 | // Render all the line comments at the beginning of the file. | |
| 61 | const src_start: usize = if (mem.startsWith(u8, tree.source, "\xEF\xBB\xBF")) 3 else 0; | |
| 62 | const comment_end_loc: usize = tree.tokens.items(.start)[0]; | |
| 63 | _ = try renderComments(ais, tree, src_start, comment_end_loc, ""); | |
| 1875 | 64 | |
| 1876 | if (for_node.label) |label| { | |
| 1877 | try renderToken(tree, ais, label, Space.None); // label | |
| 1878 | try renderToken(tree, ais, tree.nextToken(label), Space.Space); // : | |
| 1879 | } | |
| 65 | // Root is always index 0. | |
| 66 | const nodes_data = tree.nodes.items(.data); | |
| 67 | const root_decls = tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs]; | |
| 68 | if (root_decls.len == 0) return; | |
| 1880 | 69 | |
| 1881 | if (for_node.inline_token) |inline_token| { | |
| 1882 | try renderToken(tree, ais, inline_token, Space.Space); // inline | |
| 1883 | } | |
| 70 | for (root_decls) |decl| { | |
| 71 | try renderTopLevelDecl(ais, tree, decl); | |
| 72 | } | |
| 73 | } | |
| 1884 | 74 | |
| 1885 | try renderToken(tree, ais, for_node.for_token, Space.Space); // for | |
| 1886 | try renderToken(tree, ais, tree.nextToken(for_node.for_token), Space.None); // ( | |
| 1887 | try renderExpression(allocator, ais, tree, for_node.array_expr, Space.None); | |
| 75 | fn renderExtraNewline(tree: ast.Tree, ais: *Ais, node: ast.Node.Index) Error!void { | |
| 76 | return renderExtraNewlineToken(tree, ais, tree.firstToken(node)); | |
| 77 | } | |
| 1888 | 78 | |
| 1889 | const rparen = tree.nextToken(for_node.array_expr.lastToken()); | |
| 79 | fn renderExtraNewlineToken(tree: ast.Tree, ais: *Ais, first_token: ast.TokenIndex) Error!void { | |
| 80 | @panic("TODO implement renderExtraNewlineToken"); | |
| 81 | //var prev_token = first_token; | |
| 82 | //if (prev_token == 0) return; | |
| 83 | //const token_tags = tree.tokens.items(.tag); | |
| 84 | //var newline_threshold: usize = 2; | |
| 85 | //while (token_tags[prev_token - 1] == .DocComment) { | |
| 86 | // if (tree.tokenLocation(tree.token_locs[prev_token - 1].end, prev_token).line == 1) { | |
| 87 | // newline_threshold += 1; | |
| 88 | // } | |
| 89 | // prev_token -= 1; | |
| 90 | //} | |
| 91 | //const prev_token_end = tree.token_locs[prev_token - 1].end; | |
| 92 | //const loc = tree.tokenLocation(prev_token_end, first_token); | |
| 93 | //if (loc.line >= newline_threshold) { | |
| 94 | // try ais.insertNewline(); | |
| 95 | //} | |
| 96 | } | |
| 1890 | 97 | |
| 1891 | const body_is_block = for_node.body.tag.isBlock(); | |
| 1892 | const src_one_line_to_body = !body_is_block and tree.tokensOnSameLine(rparen, for_node.body.firstToken()); | |
| 1893 | const body_on_same_line = body_is_block or src_one_line_to_body; | |
| 98 | fn renderTopLevelDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index) Error!void { | |
| 99 | return renderContainerDecl(ais, tree, decl, .Newline); | |
| 100 | } | |
| 1894 | 101 | |
| 1895 | try renderToken(tree, ais, rparen, Space.Space); // ) | |
| 102 | fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void { | |
| 103 | switch (tree.nodes.items(.tag)[decl]) { | |
| 104 | .UsingNamespace, | |
| 105 | .FnProtoSimple, | |
| 106 | .FnProtoSimpleMulti, | |
| 107 | .FnProtoOne, | |
| 108 | .FnProto, | |
| 109 | .FnDecl, | |
| 110 | .GlobalVarDecl, | |
| 111 | .LocalVarDecl, | |
| 112 | .SimpleVarDecl, | |
| 113 | .AlignedVarDecl, | |
| 114 | .TestDecl, | |
| 115 | .ContainerFieldInit, | |
| 116 | .ContainerFieldAlign, | |
| 117 | .ContainerField, | |
| 118 | => @panic("TODO implement renderContainerDecl"), | |
| 1896 | 119 | |
| 1897 | const space_after_payload = if (body_on_same_line) Space.Space else Space.Newline; | |
| 1898 | try renderExpression(allocator, ais, tree, for_node.payload, space_after_payload); // |x| | |
| 120 | .Comptime => return renderExpression(ais, tree, decl, space), | |
| 1899 | 121 | |
| 1900 | const space_after_body = blk: { | |
| 1901 | if (for_node.@"else") |@"else"| { | |
| 1902 | const src_one_line_to_else = tree.tokensOnSameLine(rparen, @"else".firstToken()); | |
| 1903 | if (body_is_block or src_one_line_to_else) { | |
| 1904 | break :blk Space.Space; | |
| 1905 | } else { | |
| 1906 | break :blk Space.Newline; | |
| 1907 | } | |
| 1908 | } else { | |
| 1909 | break :blk space; | |
| 1910 | } | |
| 1911 | }; | |
| 122 | else => unreachable, | |
| 123 | } | |
| 124 | //switch (tag) { | |
| 125 | // .FnProto => { | |
| 126 | // const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl); | |
| 127 | ||
| 128 | // try renderDocComments(tree, ais, fn_proto, fn_proto.getDocComments()); | |
| 129 | ||
| 130 | // if (fn_proto.getBodyNode()) |body_node| { | |
| 131 | // try renderExpression(allocator, ais, tree, decl, .Space); | |
| 132 | // try renderExpression(allocator, ais, tree, body_node, space); | |
| 133 | // } else { | |
| 134 | // try renderExpression(allocator, ais, tree, decl, .None); | |
| 135 | // try renderToken(ais, tree, tree.nextToken(decl.lastToken()), space); | |
| 136 | // } | |
| 137 | // }, | |
| 138 | ||
| 139 | // .Use => { | |
| 140 | // const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl); | |
| 141 | ||
| 142 | // if (use_decl.visib_token) |visib_token| { | |
| 143 | // try renderToken(ais, tree, visib_token, .Space); // pub | |
| 144 | // } | |
| 145 | // try renderToken(ais, tree, use_decl.use_token, .Space); // usingnamespace | |
| 146 | // try renderExpression(allocator, ais, tree, use_decl.expr, .None); | |
| 147 | // try renderToken(ais, tree, use_decl.semicolon_token, space); // ; | |
| 148 | // }, | |
| 149 | ||
| 150 | // .VarDecl => { | |
| 151 | // const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl); | |
| 152 | ||
| 153 | // try renderDocComments(tree, ais, var_decl, var_decl.getDocComments()); | |
| 154 | // try renderVarDecl(allocator, ais, tree, var_decl); | |
| 155 | // }, | |
| 156 | ||
| 157 | // .TestDecl => { | |
| 158 | // const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl); | |
| 159 | ||
| 160 | // try renderDocComments(tree, ais, test_decl, test_decl.doc_comments); | |
| 161 | // try renderToken(ais, tree, test_decl.test_token, .Space); | |
| 162 | // if (test_decl.name) |name| | |
| 163 | // try renderExpression(allocator, ais, tree, name, .Space); | |
| 164 | // try renderExpression(allocator, ais, tree, test_decl.body_node, space); | |
| 165 | // }, | |
| 166 | ||
| 167 | // .ContainerField => { | |
| 168 | // const field = @fieldParentPtr(ast.Node.ContainerField, "base", decl); | |
| 169 | ||
| 170 | // try renderDocComments(tree, ais, field, field.doc_comments); | |
| 171 | // if (field.comptime_token) |t| { | |
| 172 | // try renderToken(ais, tree, t, .Space); // comptime | |
| 173 | // } | |
| 174 | ||
| 175 | // const src_has_trailing_comma = blk: { | |
| 176 | // const maybe_comma = tree.nextToken(field.lastToken()); | |
| 177 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 178 | // }; | |
| 179 | ||
| 180 | // // The trailing comma is emitted at the end, but if it's not present | |
| 181 | // // we still have to respect the specified `space` parameter | |
| 182 | // const last_token_space: Space = if (src_has_trailing_comma) .None else space; | |
| 183 | ||
| 184 | // if (field.type_expr == null and field.value_expr == null) { | |
| 185 | // try renderToken(ais, tree, field.name_token, last_token_space); // name | |
| 186 | // } else if (field.type_expr != null and field.value_expr == null) { | |
| 187 | // try renderToken(ais, tree, field.name_token, .None); // name | |
| 188 | // try renderToken(ais, tree, tree.nextToken(field.name_token), .Space); // : | |
| 189 | ||
| 190 | // if (field.align_expr) |align_value_expr| { | |
| 191 | // try renderExpression(allocator, ais, tree, field.type_expr.?, .Space); // type | |
| 192 | // const lparen_token = tree.prevToken(align_value_expr.firstToken()); | |
| 193 | // const align_kw = tree.prevToken(lparen_token); | |
| 194 | // const rparen_token = tree.nextToken(align_value_expr.lastToken()); | |
| 195 | // try renderToken(ais, tree, align_kw, .None); // align | |
| 196 | // try renderToken(ais, tree, lparen_token, .None); // ( | |
| 197 | // try renderExpression(allocator, ais, tree, align_value_expr, .None); // alignment | |
| 198 | // try renderToken(ais, tree, rparen_token, last_token_space); // ) | |
| 199 | // } else { | |
| 200 | // try renderExpression(allocator, ais, tree, field.type_expr.?, last_token_space); // type | |
| 201 | // } | |
| 202 | // } else if (field.type_expr == null and field.value_expr != null) { | |
| 203 | // try renderToken(ais, tree, field.name_token, .Space); // name | |
| 204 | // try renderToken(ais, tree, tree.nextToken(field.name_token), .Space); // = | |
| 205 | // try renderExpression(allocator, ais, tree, field.value_expr.?, last_token_space); // value | |
| 206 | // } else { | |
| 207 | // try renderToken(ais, tree, field.name_token, .None); // name | |
| 208 | // try renderToken(ais, tree, tree.nextToken(field.name_token), .Space); // : | |
| 209 | ||
| 210 | // if (field.align_expr) |align_value_expr| { | |
| 211 | // try renderExpression(allocator, ais, tree, field.type_expr.?, .Space); // type | |
| 212 | // const lparen_token = tree.prevToken(align_value_expr.firstToken()); | |
| 213 | // const align_kw = tree.prevToken(lparen_token); | |
| 214 | // const rparen_token = tree.nextToken(align_value_expr.lastToken()); | |
| 215 | // try renderToken(ais, tree, align_kw, .None); // align | |
| 216 | // try renderToken(ais, tree, lparen_token, .None); // ( | |
| 217 | // try renderExpression(allocator, ais, tree, align_value_expr, .None); // alignment | |
| 218 | // try renderToken(ais, tree, rparen_token, .Space); // ) | |
| 219 | // } else { | |
| 220 | // try renderExpression(allocator, ais, tree, field.type_expr.?, .Space); // type | |
| 221 | // } | |
| 222 | // try renderToken(ais, tree, tree.prevToken(field.value_expr.?.firstToken()), .Space); // = | |
| 223 | // try renderExpression(allocator, ais, tree, field.value_expr.?, last_token_space); // value | |
| 224 | // } | |
| 225 | ||
| 226 | // if (src_has_trailing_comma) { | |
| 227 | // const comma = tree.nextToken(field.lastToken()); | |
| 228 | // try renderToken(ais, tree, comma, space); | |
| 229 | // } | |
| 230 | // }, | |
| 231 | ||
| 232 | // .DocComment => { | |
| 233 | // const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl); | |
| 234 | // const kind = tree.token_tags[comment.first_line]; | |
| 235 | // try renderToken(ais, tree, comment.first_line, .Newline); | |
| 236 | // var tok_i = comment.first_line + 1; | |
| 237 | // while (true) : (tok_i += 1) { | |
| 238 | // const tok_id = tree.token_tags[tok_i]; | |
| 239 | // if (tok_id == kind) { | |
| 240 | // try renderToken(ais, tree, tok_i, .Newline); | |
| 241 | // } else if (tok_id == .LineComment) { | |
| 242 | // continue; | |
| 243 | // } else { | |
| 244 | // break; | |
| 245 | // } | |
| 246 | // } | |
| 247 | // }, | |
| 248 | // else => unreachable, | |
| 249 | //} | |
| 250 | } | |
| 1912 | 251 | |
| 252 | fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void { | |
| 253 | const token_tags = tree.tokens.items(.tag); | |
| 254 | const main_tokens = tree.nodes.items(.main_token); | |
| 255 | switch (tree.nodes.items(.tag)[node]) { | |
| 256 | //.Identifier, | |
| 257 | //.IntegerLiteral, | |
| 258 | //.FloatLiteral, | |
| 259 | //.StringLiteral, | |
| 260 | //.CharLiteral, | |
| 261 | //.BoolLiteral, | |
| 262 | //.NullLiteral, | |
| 263 | //.Unreachable, | |
| 264 | //.ErrorType, | |
| 265 | //.UndefinedLiteral, | |
| 266 | //=> { | |
| 267 | // const casted_node = base.cast(ast.Node.OneToken).?; | |
| 268 | // return renderToken(ais, tree, casted_node.token, space); | |
| 269 | //}, | |
| 270 | ||
| 271 | //.AnyType => { | |
| 272 | // const any_type = base.castTag(.AnyType).?; | |
| 273 | // if (mem.eql(u8, tree.tokenSlice(any_type.token), "var")) { | |
| 274 | // // TODO remove in next release cycle | |
| 275 | // try ais.writer().writeAll("anytype"); | |
| 276 | // if (space == .Comma) try ais.writer().writeAll(",\n"); | |
| 277 | // return; | |
| 278 | // } | |
| 279 | // return renderToken(ais, tree, any_type.token, space); | |
| 280 | //}, | |
| 281 | .Block => { | |
| 282 | const lbrace = main_tokens[node]; | |
| 283 | if (token_tags[lbrace - 1] == .Colon and | |
| 284 | token_tags[lbrace - 2] == .Identifier) | |
| 1913 | 285 | { |
| 1914 | if (!body_on_same_line) ais.pushIndent(); | |
| 1915 | defer if (!body_on_same_line) ais.popIndent(); | |
| 1916 | try renderExpression(allocator, ais, tree, for_node.body, space_after_body); // { body } | |
| 1917 | } | |
| 1918 | ||
| 1919 | if (for_node.@"else") |@"else"| { | |
| 1920 | return renderExpression(allocator, ais, tree, &@"else".base, space); // else | |
| 1921 | } | |
| 1922 | }, | |
| 1923 | ||
| 1924 | .If => { | |
| 1925 | const if_node = @fieldParentPtr(ast.Node.If, "base", base); | |
| 1926 | ||
| 1927 | const lparen = tree.nextToken(if_node.if_token); | |
| 1928 | const rparen = tree.nextToken(if_node.condition.lastToken()); | |
| 1929 | ||
| 1930 | try renderToken(tree, ais, if_node.if_token, Space.Space); // if | |
| 1931 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 1932 | ||
| 1933 | try renderExpression(allocator, ais, tree, if_node.condition, Space.None); // condition | |
| 1934 | ||
| 1935 | const body_is_if_block = if_node.body.tag == .If; | |
| 1936 | const body_is_block = nodeIsBlock(if_node.body); | |
| 1937 | ||
| 1938 | if (body_is_if_block) { | |
| 1939 | try renderExtraNewline(tree, ais, if_node.body); | |
| 1940 | } else if (body_is_block) { | |
| 1941 | const after_rparen_space = if (if_node.payload == null) Space.BlockStart else Space.Space; | |
| 1942 | try renderToken(tree, ais, rparen, after_rparen_space); // ) | |
| 1943 | ||
| 1944 | if (if_node.payload) |payload| { | |
| 1945 | try renderExpression(allocator, ais, tree, payload, Space.BlockStart); // |x| | |
| 1946 | } | |
| 1947 | ||
| 1948 | if (if_node.@"else") |@"else"| { | |
| 1949 | try renderExpression(allocator, ais, tree, if_node.body, Space.SpaceOrOutdent); | |
| 1950 | return renderExpression(allocator, ais, tree, &@"else".base, space); | |
| 1951 | } else { | |
| 1952 | return renderExpression(allocator, ais, tree, if_node.body, space); | |
| 1953 | } | |
| 1954 | } | |
| 1955 | ||
| 1956 | const src_has_newline = !tree.tokensOnSameLine(rparen, if_node.body.lastToken()); | |
| 1957 | ||
| 1958 | if (src_has_newline) { | |
| 1959 | const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space; | |
| 1960 | ||
| 1961 | { | |
| 1962 | ais.pushIndent(); | |
| 1963 | defer ais.popIndent(); | |
| 1964 | try renderToken(tree, ais, rparen, after_rparen_space); // ) | |
| 1965 | } | |
| 1966 | ||
| 1967 | if (if_node.payload) |payload| { | |
| 1968 | try renderExpression(allocator, ais, tree, payload, Space.Newline); | |
| 1969 | } | |
| 1970 | ||
| 1971 | if (if_node.@"else") |@"else"| { | |
| 1972 | const else_is_block = nodeIsBlock(@"else".body); | |
| 1973 | ||
| 1974 | { | |
| 1975 | ais.pushIndent(); | |
| 1976 | defer ais.popIndent(); | |
| 1977 | try renderExpression(allocator, ais, tree, if_node.body, Space.Newline); | |
| 1978 | } | |
| 1979 | ||
| 1980 | if (else_is_block) { | |
| 1981 | try renderToken(tree, ais, @"else".else_token, Space.Space); // else | |
| 1982 | ||
| 1983 | if (@"else".payload) |payload| { | |
| 1984 | try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 1985 | } | |
| 1986 | ||
| 1987 | return renderExpression(allocator, ais, tree, @"else".body, space); | |
| 1988 | } else { | |
| 1989 | const after_else_space = if (@"else".payload == null) Space.Newline else Space.Space; | |
| 1990 | try renderToken(tree, ais, @"else".else_token, after_else_space); // else | |
| 1991 | ||
| 1992 | if (@"else".payload) |payload| { | |
| 1993 | try renderExpression(allocator, ais, tree, payload, Space.Newline); | |
| 1994 | } | |
| 1995 | ||
| 1996 | ais.pushIndent(); | |
| 1997 | defer ais.popIndent(); | |
| 1998 | return renderExpression(allocator, ais, tree, @"else".body, space); | |
| 1999 | } | |
| 2000 | } else { | |
| 2001 | ais.pushIndent(); | |
| 2002 | defer ais.popIndent(); | |
| 2003 | return renderExpression(allocator, ais, tree, if_node.body, space); | |
| 2004 | } | |
| 2005 | } | |
| 2006 | ||
| 2007 | // Single line if statement | |
| 2008 | ||
| 2009 | try renderToken(tree, ais, rparen, Space.Space); // ) | |
| 2010 | ||
| 2011 | if (if_node.payload) |payload| { | |
| 2012 | try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 2013 | } | |
| 2014 | ||
| 2015 | if (if_node.@"else") |@"else"| { | |
| 2016 | try renderExpression(allocator, ais, tree, if_node.body, Space.Space); | |
| 2017 | try renderToken(tree, ais, @"else".else_token, Space.Space); | |
| 2018 | ||
| 2019 | if (@"else".payload) |payload| { | |
| 2020 | try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 2021 | } | |
| 2022 | ||
| 2023 | return renderExpression(allocator, ais, tree, @"else".body, space); | |
| 2024 | } else { | |
| 2025 | return renderExpression(allocator, ais, tree, if_node.body, space); | |
| 286 | try renderToken(ais, tree, lbrace - 2, .None); | |
| 287 | try renderToken(ais, tree, lbrace - 1, .Space); | |
| 2026 | 288 | } |
| 2027 | }, | |
| 289 | const nodes_data = tree.nodes.items(.data); | |
| 290 | const statements = tree.extra_data[nodes_data[node].lhs..nodes_data[node].rhs]; | |
| 2028 | 291 | |
| 2029 | .Asm => { | |
| 2030 | const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base); | |
| 2031 | ||
| 2032 | try renderToken(tree, ais, asm_node.asm_token, Space.Space); // asm | |
| 2033 | ||
| 2034 | if (asm_node.volatile_token) |volatile_token| { | |
| 2035 | try renderToken(tree, ais, volatile_token, Space.Space); // volatile | |
| 2036 | try renderToken(tree, ais, tree.nextToken(volatile_token), Space.None); // ( | |
| 292 | if (statements.len == 0) { | |
| 293 | ais.pushIndentNextLine(); | |
| 294 | try renderToken(ais, tree, lbrace, .None); | |
| 295 | ais.popIndent(); | |
| 296 | const rbrace = lbrace + 1; | |
| 297 | return renderToken(ais, tree, rbrace, space); | |
| 2037 | 298 | } else { |
| 2038 | try renderToken(tree, ais, tree.nextToken(asm_node.asm_token), Space.None); // ( | |
| 2039 | } | |
| 299 | ais.pushIndentNextLine(); | |
| 2040 | 300 | |
| 2041 | asmblk: { | |
| 2042 | ais.pushIndent(); | |
| 2043 | defer ais.popIndent(); | |
| 301 | try renderToken(ais, tree, lbrace, .Newline); | |
| 2044 | 302 | |
| 2045 | if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) { | |
| 2046 | try renderExpression(allocator, ais, tree, asm_node.template, Space.None); | |
| 2047 | break :asmblk; | |
| 2048 | } | |
| 303 | for (statements) |statement, i| { | |
| 304 | try renderStatement(ais, tree, statement); | |
| 2049 | 305 | |
| 2050 | try renderExpression(allocator, ais, tree, asm_node.template, Space.Newline); | |
| 2051 | ||
| 2052 | ais.setIndentDelta(asm_indent_delta); | |
| 2053 | defer ais.setIndentDelta(indent_delta); | |
| 2054 | ||
| 2055 | const colon1 = tree.nextToken(asm_node.template.lastToken()); | |
| 2056 | ||
| 2057 | const colon2 = if (asm_node.outputs.len == 0) blk: { | |
| 2058 | try renderToken(tree, ais, colon1, Space.Newline); // : | |
| 2059 | ||
| 2060 | break :blk tree.nextToken(colon1); | |
| 2061 | } else blk: { | |
| 2062 | try renderToken(tree, ais, colon1, Space.Space); // : | |
| 2063 | ||
| 2064 | ais.pushIndent(); | |
| 2065 | defer ais.popIndent(); | |
| 2066 | ||
| 2067 | for (asm_node.outputs) |*asm_output, i| { | |
| 2068 | if (i + 1 < asm_node.outputs.len) { | |
| 2069 | const next_asm_output = asm_node.outputs[i + 1]; | |
| 2070 | try renderAsmOutput(allocator, ais, tree, asm_output, Space.None); | |
| 2071 | ||
| 2072 | const comma = tree.prevToken(next_asm_output.firstToken()); | |
| 2073 | try renderToken(tree, ais, comma, Space.Newline); // , | |
| 2074 | try renderExtraNewlineToken(tree, ais, next_asm_output.firstToken()); | |
| 2075 | } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) { | |
| 2076 | try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline); | |
| 2077 | break :asmblk; | |
| 2078 | } else { | |
| 2079 | try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline); | |
| 2080 | const comma_or_colon = tree.nextToken(asm_output.lastToken()); | |
| 2081 | break :blk switch (tree.token_ids[comma_or_colon]) { | |
| 2082 | .Comma => tree.nextToken(comma_or_colon), | |
| 2083 | else => comma_or_colon, | |
| 2084 | }; | |
| 2085 | } | |
| 2086 | } | |
| 2087 | unreachable; | |
| 2088 | }; | |
| 2089 | ||
| 2090 | const colon3 = if (asm_node.inputs.len == 0) blk: { | |
| 2091 | try renderToken(tree, ais, colon2, Space.Newline); // : | |
| 2092 | break :blk tree.nextToken(colon2); | |
| 2093 | } else blk: { | |
| 2094 | try renderToken(tree, ais, colon2, Space.Space); // : | |
| 2095 | ais.pushIndent(); | |
| 2096 | defer ais.popIndent(); | |
| 2097 | for (asm_node.inputs) |*asm_input, i| { | |
| 2098 | if (i + 1 < asm_node.inputs.len) { | |
| 2099 | const next_asm_input = &asm_node.inputs[i + 1]; | |
| 2100 | try renderAsmInput(allocator, ais, tree, asm_input, Space.None); | |
| 2101 | ||
| 2102 | const comma = tree.prevToken(next_asm_input.firstToken()); | |
| 2103 | try renderToken(tree, ais, comma, Space.Newline); // , | |
| 2104 | try renderExtraNewlineToken(tree, ais, next_asm_input.firstToken()); | |
| 2105 | } else if (asm_node.clobbers.len == 0) { | |
| 2106 | try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline); | |
| 2107 | break :asmblk; | |
| 2108 | } else { | |
| 2109 | try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline); | |
| 2110 | const comma_or_colon = tree.nextToken(asm_input.lastToken()); | |
| 2111 | break :blk switch (tree.token_ids[comma_or_colon]) { | |
| 2112 | .Comma => tree.nextToken(comma_or_colon), | |
| 2113 | else => comma_or_colon, | |
| 2114 | }; | |
| 2115 | } | |
| 2116 | } | |
| 2117 | unreachable; | |
| 2118 | }; | |
| 2119 | ||
| 2120 | try renderToken(tree, ais, colon3, Space.Space); // : | |
| 2121 | ais.pushIndent(); | |
| 2122 | defer ais.popIndent(); | |
| 2123 | for (asm_node.clobbers) |clobber_node, i| { | |
| 2124 | if (i + 1 >= asm_node.clobbers.len) { | |
| 2125 | try renderExpression(allocator, ais, tree, clobber_node, Space.Newline); | |
| 2126 | break :asmblk; | |
| 2127 | } else { | |
| 2128 | try renderExpression(allocator, ais, tree, clobber_node, Space.None); | |
| 2129 | const comma = tree.nextToken(clobber_node.lastToken()); | |
| 2130 | try renderToken(tree, ais, comma, Space.Space); // , | |
| 306 | if (i + 1 < statements.len) { | |
| 307 | try renderExtraNewline(tree, ais, statements[i + 1]); | |
| 2131 | 308 | } |
| 2132 | 309 | } |
| 310 | ais.popIndent(); | |
| 311 | const rbrace = tree.lastToken(statements[statements.len - 1]) + 1; | |
| 312 | return renderToken(ais, tree, rbrace, space); | |
| 2133 | 313 | } |
| 2134 | ||
| 2135 | return renderToken(tree, ais, asm_node.rparen, space); | |
| 2136 | 314 | }, |
| 2137 | 315 | |
| 2138 | .EnumLiteral => { | |
| 2139 | const enum_literal = @fieldParentPtr(ast.Node.EnumLiteral, "base", base); | |
| 316 | //.Defer => { | |
| 317 | // const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base); | |
| 2140 | 318 | |
| 2141 | try renderToken(tree, ais, enum_literal.dot, Space.None); // . | |
| 2142 | return renderToken(tree, ais, enum_literal.name, space); // name | |
| 319 | // try renderToken(ais, tree, defer_node.defer_token, Space.Space); | |
| 320 | // if (defer_node.payload) |payload| { | |
| 321 | // try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 322 | // } | |
| 323 | // return renderExpression(allocator, ais, tree, defer_node.expr, space); | |
| 324 | //}, | |
| 325 | .Comptime => { | |
| 326 | const comptime_token = tree.nodes.items(.main_token)[node]; | |
| 327 | const block = tree.nodes.items(.data)[node].lhs; | |
| 328 | try renderToken(ais, tree, comptime_token, .Space); | |
| 329 | return renderExpression(ais, tree, block, space); | |
| 2143 | 330 | }, |
| 2144 | ||
| 2145 | .ContainerField, | |
| 2146 | .Root, | |
| 2147 | .VarDecl, | |
| 2148 | .Use, | |
| 2149 | .TestDecl, | |
| 2150 | => unreachable, | |
| 331 | //.Nosuspend => { | |
| 332 | // const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base); | |
| 333 | // if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) { | |
| 334 | // // TODO: remove this | |
| 335 | // try ais.writer().writeAll("nosuspend "); | |
| 336 | // } else { | |
| 337 | // try renderToken(ais, tree, nosuspend_node.nosuspend_token, Space.Space); | |
| 338 | // } | |
| 339 | // return renderExpression(allocator, ais, tree, nosuspend_node.expr, space); | |
| 340 | //}, | |
| 341 | ||
| 342 | //.Suspend => { | |
| 343 | // const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base); | |
| 344 | ||
| 345 | // if (suspend_node.body) |body| { | |
| 346 | // try renderToken(ais, tree, suspend_node.suspend_token, Space.Space); | |
| 347 | // return renderExpression(allocator, ais, tree, body, space); | |
| 348 | // } else { | |
| 349 | // return renderToken(ais, tree, suspend_node.suspend_token, space); | |
| 350 | // } | |
| 351 | //}, | |
| 352 | ||
| 353 | //.Catch => { | |
| 354 | // const infix_op_node = @fieldParentPtr(ast.Node.Catch, "base", base); | |
| 355 | ||
| 356 | // const op_space = Space.Space; | |
| 357 | // try renderExpression(allocator, ais, tree, infix_op_node.lhs, op_space); | |
| 358 | ||
| 359 | // const after_op_space = blk: { | |
| 360 | // const same_line = tree.tokensOnSameLine(infix_op_node.op_token, tree.nextToken(infix_op_node.op_token)); | |
| 361 | // break :blk if (same_line) op_space else Space.Newline; | |
| 362 | // }; | |
| 363 | ||
| 364 | // try renderToken(ais, tree, infix_op_node.op_token, after_op_space); | |
| 365 | ||
| 366 | // if (infix_op_node.payload) |payload| { | |
| 367 | // try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 368 | // } | |
| 369 | ||
| 370 | // ais.pushIndentOneShot(); | |
| 371 | // return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); | |
| 372 | //}, | |
| 373 | ||
| 374 | //.Add, | |
| 375 | //.AddWrap, | |
| 376 | //.ArrayCat, | |
| 377 | //.ArrayMult, | |
| 378 | //.Assign, | |
| 379 | //.AssignBitAnd, | |
| 380 | //.AssignBitOr, | |
| 381 | //.AssignBitShiftLeft, | |
| 382 | //.AssignBitShiftRight, | |
| 383 | //.AssignBitXor, | |
| 384 | //.AssignDiv, | |
| 385 | //.AssignSub, | |
| 386 | //.AssignSubWrap, | |
| 387 | //.AssignMod, | |
| 388 | //.AssignAdd, | |
| 389 | //.AssignAddWrap, | |
| 390 | //.AssignMul, | |
| 391 | //.AssignMulWrap, | |
| 392 | //.BangEqual, | |
| 393 | //.BitAnd, | |
| 394 | //.BitOr, | |
| 395 | //.BitShiftLeft, | |
| 396 | //.BitShiftRight, | |
| 397 | //.BitXor, | |
| 398 | //.BoolAnd, | |
| 399 | //.BoolOr, | |
| 400 | //.Div, | |
| 401 | //.EqualEqual, | |
| 402 | //.ErrorUnion, | |
| 403 | //.GreaterOrEqual, | |
| 404 | //.GreaterThan, | |
| 405 | //.LessOrEqual, | |
| 406 | //.LessThan, | |
| 407 | //.MergeErrorSets, | |
| 408 | //.Mod, | |
| 409 | //.Mul, | |
| 410 | //.MulWrap, | |
| 411 | //.Period, | |
| 412 | //.Range, | |
| 413 | //.Sub, | |
| 414 | //.SubWrap, | |
| 415 | //.OrElse, | |
| 416 | //=> { | |
| 417 | // const infix_op_node = @fieldParentPtr(ast.Node.SimpleInfixOp, "base", base); | |
| 418 | ||
| 419 | // const op_space = switch (base.tag) { | |
| 420 | // .Period, .ErrorUnion, .Range => Space.None, | |
| 421 | // else => Space.Space, | |
| 422 | // }; | |
| 423 | // try renderExpression(allocator, ais, tree, infix_op_node.lhs, op_space); | |
| 424 | ||
| 425 | // const after_op_space = blk: { | |
| 426 | // const loc = tree.tokenLocation(tree.token_locs[infix_op_node.op_token].end, tree.nextToken(infix_op_node.op_token)); | |
| 427 | // break :blk if (loc.line == 0) op_space else Space.Newline; | |
| 428 | // }; | |
| 429 | ||
| 430 | // { | |
| 431 | // ais.pushIndent(); | |
| 432 | // defer ais.popIndent(); | |
| 433 | // try renderToken(ais, tree, infix_op_node.op_token, after_op_space); | |
| 434 | // } | |
| 435 | // ais.pushIndentOneShot(); | |
| 436 | // return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); | |
| 437 | //}, | |
| 438 | ||
| 439 | //.BitNot, | |
| 440 | //.BoolNot, | |
| 441 | //.Negation, | |
| 442 | //.NegationWrap, | |
| 443 | //.OptionalType, | |
| 444 | //.AddressOf, | |
| 445 | //=> { | |
| 446 | // const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base); | |
| 447 | // try renderToken(ais, tree, casted_node.op_token, Space.None); | |
| 448 | // return renderExpression(allocator, ais, tree, casted_node.rhs, space); | |
| 449 | //}, | |
| 450 | ||
| 451 | //.Try, | |
| 452 | //.Resume, | |
| 453 | //.Await, | |
| 454 | //=> { | |
| 455 | // const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base); | |
| 456 | // try renderToken(ais, tree, casted_node.op_token, Space.Space); | |
| 457 | // return renderExpression(allocator, ais, tree, casted_node.rhs, space); | |
| 458 | //}, | |
| 459 | ||
| 460 | //.ArrayType => { | |
| 461 | // const array_type = @fieldParentPtr(ast.Node.ArrayType, "base", base); | |
| 462 | // return renderArrayType( | |
| 463 | // allocator, | |
| 464 | // ais, | |
| 465 | // tree, | |
| 466 | // array_type.op_token, | |
| 467 | // array_type.rhs, | |
| 468 | // array_type.len_expr, | |
| 469 | // null, | |
| 470 | // space, | |
| 471 | // ); | |
| 472 | //}, | |
| 473 | //.ArrayTypeSentinel => { | |
| 474 | // const array_type = @fieldParentPtr(ast.Node.ArrayTypeSentinel, "base", base); | |
| 475 | // return renderArrayType( | |
| 476 | // allocator, | |
| 477 | // ais, | |
| 478 | // tree, | |
| 479 | // array_type.op_token, | |
| 480 | // array_type.rhs, | |
| 481 | // array_type.len_expr, | |
| 482 | // array_type.sentinel, | |
| 483 | // space, | |
| 484 | // ); | |
| 485 | //}, | |
| 486 | ||
| 487 | //.PtrType => { | |
| 488 | // const ptr_type = @fieldParentPtr(ast.Node.PtrType, "base", base); | |
| 489 | // const op_tok_id = tree.token_tags[ptr_type.op_token]; | |
| 490 | // switch (op_tok_id) { | |
| 491 | // .Asterisk, .AsteriskAsterisk => try ais.writer().writeByte('*'), | |
| 492 | // .LBracket => if (tree.token_tags[ptr_type.op_token + 2] == .Identifier) | |
| 493 | // try ais.writer().writeAll("[*c") | |
| 494 | // else | |
| 495 | // try ais.writer().writeAll("[*"), | |
| 496 | // else => unreachable, | |
| 497 | // } | |
| 498 | // if (ptr_type.ptr_info.sentinel) |sentinel| { | |
| 499 | // const colon_token = tree.prevToken(sentinel.firstToken()); | |
| 500 | // try renderToken(ais, tree, colon_token, Space.None); // : | |
| 501 | // const sentinel_space = switch (op_tok_id) { | |
| 502 | // .LBracket => Space.None, | |
| 503 | // else => Space.Space, | |
| 504 | // }; | |
| 505 | // try renderExpression(allocator, ais, tree, sentinel, sentinel_space); | |
| 506 | // } | |
| 507 | // switch (op_tok_id) { | |
| 508 | // .Asterisk, .AsteriskAsterisk => {}, | |
| 509 | // .LBracket => try ais.writer().writeByte(']'), | |
| 510 | // else => unreachable, | |
| 511 | // } | |
| 512 | // if (ptr_type.ptr_info.allowzero_token) |allowzero_token| { | |
| 513 | // try renderToken(ais, tree, allowzero_token, Space.Space); // allowzero | |
| 514 | // } | |
| 515 | // if (ptr_type.ptr_info.align_info) |align_info| { | |
| 516 | // const lparen_token = tree.prevToken(align_info.node.firstToken()); | |
| 517 | // const align_token = tree.prevToken(lparen_token); | |
| 518 | ||
| 519 | // try renderToken(ais, tree, align_token, Space.None); // align | |
| 520 | // try renderToken(ais, tree, lparen_token, Space.None); // ( | |
| 521 | ||
| 522 | // try renderExpression(allocator, ais, tree, align_info.node, Space.None); | |
| 523 | ||
| 524 | // if (align_info.bit_range) |bit_range| { | |
| 525 | // const colon1 = tree.prevToken(bit_range.start.firstToken()); | |
| 526 | // const colon2 = tree.prevToken(bit_range.end.firstToken()); | |
| 527 | ||
| 528 | // try renderToken(ais, tree, colon1, Space.None); // : | |
| 529 | // try renderExpression(allocator, ais, tree, bit_range.start, Space.None); | |
| 530 | // try renderToken(ais, tree, colon2, Space.None); // : | |
| 531 | // try renderExpression(allocator, ais, tree, bit_range.end, Space.None); | |
| 532 | ||
| 533 | // const rparen_token = tree.nextToken(bit_range.end.lastToken()); | |
| 534 | // try renderToken(ais, tree, rparen_token, Space.Space); // ) | |
| 535 | // } else { | |
| 536 | // const rparen_token = tree.nextToken(align_info.node.lastToken()); | |
| 537 | // try renderToken(ais, tree, rparen_token, Space.Space); // ) | |
| 538 | // } | |
| 539 | // } | |
| 540 | // if (ptr_type.ptr_info.const_token) |const_token| { | |
| 541 | // try renderToken(ais, tree, const_token, Space.Space); // const | |
| 542 | // } | |
| 543 | // if (ptr_type.ptr_info.volatile_token) |volatile_token| { | |
| 544 | // try renderToken(ais, tree, volatile_token, Space.Space); // volatile | |
| 545 | // } | |
| 546 | // return renderExpression(allocator, ais, tree, ptr_type.rhs, space); | |
| 547 | //}, | |
| 548 | ||
| 549 | //.SliceType => { | |
| 550 | // const slice_type = @fieldParentPtr(ast.Node.SliceType, "base", base); | |
| 551 | // try renderToken(ais, tree, slice_type.op_token, Space.None); // [ | |
| 552 | // if (slice_type.ptr_info.sentinel) |sentinel| { | |
| 553 | // const colon_token = tree.prevToken(sentinel.firstToken()); | |
| 554 | // try renderToken(ais, tree, colon_token, Space.None); // : | |
| 555 | // try renderExpression(allocator, ais, tree, sentinel, Space.None); | |
| 556 | // try renderToken(ais, tree, tree.nextToken(sentinel.lastToken()), Space.None); // ] | |
| 557 | // } else { | |
| 558 | // try renderToken(ais, tree, tree.nextToken(slice_type.op_token), Space.None); // ] | |
| 559 | // } | |
| 560 | ||
| 561 | // if (slice_type.ptr_info.allowzero_token) |allowzero_token| { | |
| 562 | // try renderToken(ais, tree, allowzero_token, Space.Space); // allowzero | |
| 563 | // } | |
| 564 | // if (slice_type.ptr_info.align_info) |align_info| { | |
| 565 | // const lparen_token = tree.prevToken(align_info.node.firstToken()); | |
| 566 | // const align_token = tree.prevToken(lparen_token); | |
| 567 | ||
| 568 | // try renderToken(ais, tree, align_token, Space.None); // align | |
| 569 | // try renderToken(ais, tree, lparen_token, Space.None); // ( | |
| 570 | ||
| 571 | // try renderExpression(allocator, ais, tree, align_info.node, Space.None); | |
| 572 | ||
| 573 | // if (align_info.bit_range) |bit_range| { | |
| 574 | // const colon1 = tree.prevToken(bit_range.start.firstToken()); | |
| 575 | // const colon2 = tree.prevToken(bit_range.end.firstToken()); | |
| 576 | ||
| 577 | // try renderToken(ais, tree, colon1, Space.None); // : | |
| 578 | // try renderExpression(allocator, ais, tree, bit_range.start, Space.None); | |
| 579 | // try renderToken(ais, tree, colon2, Space.None); // : | |
| 580 | // try renderExpression(allocator, ais, tree, bit_range.end, Space.None); | |
| 581 | ||
| 582 | // const rparen_token = tree.nextToken(bit_range.end.lastToken()); | |
| 583 | // try renderToken(ais, tree, rparen_token, Space.Space); // ) | |
| 584 | // } else { | |
| 585 | // const rparen_token = tree.nextToken(align_info.node.lastToken()); | |
| 586 | // try renderToken(ais, tree, rparen_token, Space.Space); // ) | |
| 587 | // } | |
| 588 | // } | |
| 589 | // if (slice_type.ptr_info.const_token) |const_token| { | |
| 590 | // try renderToken(ais, tree, const_token, Space.Space); | |
| 591 | // } | |
| 592 | // if (slice_type.ptr_info.volatile_token) |volatile_token| { | |
| 593 | // try renderToken(ais, tree, volatile_token, Space.Space); | |
| 594 | // } | |
| 595 | // return renderExpression(allocator, ais, tree, slice_type.rhs, space); | |
| 596 | //}, | |
| 597 | ||
| 598 | //.ArrayInitializer, .ArrayInitializerDot => { | |
| 599 | // var rtoken: ast.TokenIndex = undefined; | |
| 600 | // var exprs: []ast.Node.Index = undefined; | |
| 601 | // const lhs: union(enum) { dot: ast.TokenIndex, node: ast.Node.Index } = switch (base.tag) { | |
| 602 | // .ArrayInitializerDot => blk: { | |
| 603 | // const casted = @fieldParentPtr(ast.Node.ArrayInitializerDot, "base", base); | |
| 604 | // rtoken = casted.rtoken; | |
| 605 | // exprs = casted.list(); | |
| 606 | // break :blk .{ .dot = casted.dot }; | |
| 607 | // }, | |
| 608 | // .ArrayInitializer => blk: { | |
| 609 | // const casted = @fieldParentPtr(ast.Node.ArrayInitializer, "base", base); | |
| 610 | // rtoken = casted.rtoken; | |
| 611 | // exprs = casted.list(); | |
| 612 | // break :blk .{ .node = casted.lhs }; | |
| 613 | // }, | |
| 614 | // else => unreachable, | |
| 615 | // }; | |
| 616 | ||
| 617 | // const lbrace = switch (lhs) { | |
| 618 | // .dot => |dot| tree.nextToken(dot), | |
| 619 | // .node => |node| tree.nextToken(node.lastToken()), | |
| 620 | // }; | |
| 621 | ||
| 622 | // switch (lhs) { | |
| 623 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | |
| 624 | // .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 625 | // } | |
| 626 | ||
| 627 | // if (exprs.len == 0) { | |
| 628 | // try renderToken(ais, tree, lbrace, Space.None); | |
| 629 | // return renderToken(ais, tree, rtoken, space); | |
| 630 | // } | |
| 631 | ||
| 632 | // if (exprs.len == 1 and exprs[0].tag != .MultilineStringLiteral and tree.token_tags[exprs[0].*.lastToken() + 1] == .RBrace) { | |
| 633 | // const expr = exprs[0]; | |
| 634 | ||
| 635 | // try renderToken(ais, tree, lbrace, Space.None); | |
| 636 | // try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 637 | // return renderToken(ais, tree, rtoken, space); | |
| 638 | // } | |
| 639 | ||
| 640 | // // scan to find row size | |
| 641 | // if (rowSize(tree, exprs, rtoken) != null) { | |
| 642 | // { | |
| 643 | // ais.pushIndentNextLine(); | |
| 644 | // defer ais.popIndent(); | |
| 645 | // try renderToken(ais, tree, lbrace, Space.Newline); | |
| 646 | ||
| 647 | // var expr_index: usize = 0; | |
| 648 | // while (rowSize(tree, exprs[expr_index..], rtoken)) |row_size| { | |
| 649 | // const row_exprs = exprs[expr_index..]; | |
| 650 | // // A place to store the width of each expression and its column's maximum | |
| 651 | // var widths = try allocator.alloc(usize, row_exprs.len + row_size); | |
| 652 | // defer allocator.free(widths); | |
| 653 | // mem.set(usize, widths, 0); | |
| 654 | ||
| 655 | // var expr_newlines = try allocator.alloc(bool, row_exprs.len); | |
| 656 | // defer allocator.free(expr_newlines); | |
| 657 | // mem.set(bool, expr_newlines, false); | |
| 658 | ||
| 659 | // var expr_widths = widths[0 .. widths.len - row_size]; | |
| 660 | // var column_widths = widths[widths.len - row_size ..]; | |
| 661 | ||
| 662 | // // Find next row with trailing comment (if any) to end the current section | |
| 663 | // var section_end = sec_end: { | |
| 664 | // var this_line_first_expr: usize = 0; | |
| 665 | // var this_line_size = rowSize(tree, row_exprs, rtoken); | |
| 666 | // for (row_exprs) |expr, i| { | |
| 667 | // // Ignore comment on first line of this section | |
| 668 | // if (i == 0 or tree.tokensOnSameLine(row_exprs[0].firstToken(), expr.lastToken())) continue; | |
| 669 | // // Track start of line containing comment | |
| 670 | // if (!tree.tokensOnSameLine(row_exprs[this_line_first_expr].firstToken(), expr.lastToken())) { | |
| 671 | // this_line_first_expr = i; | |
| 672 | // this_line_size = rowSize(tree, row_exprs[this_line_first_expr..], rtoken); | |
| 673 | // } | |
| 674 | ||
| 675 | // const maybe_comma = expr.lastToken() + 1; | |
| 676 | // const maybe_comment = expr.lastToken() + 2; | |
| 677 | // if (maybe_comment < tree.token_tags.len) { | |
| 678 | // if (tree.token_tags[maybe_comma] == .Comma and | |
| 679 | // tree.token_tags[maybe_comment] == .LineComment and | |
| 680 | // tree.tokensOnSameLine(expr.lastToken(), maybe_comment)) | |
| 681 | // { | |
| 682 | // var comment_token_loc = tree.token_locs[maybe_comment]; | |
| 683 | // const comment_is_empty = mem.trimRight(u8, tree.tokenSliceLoc(comment_token_loc), " ").len == 2; | |
| 684 | // if (!comment_is_empty) { | |
| 685 | // // Found row ending in comment | |
| 686 | // break :sec_end i - this_line_size.? + 1; | |
| 687 | // } | |
| 688 | // } | |
| 689 | // } | |
| 690 | // } | |
| 691 | // break :sec_end row_exprs.len; | |
| 692 | // }; | |
| 693 | // expr_index += section_end; | |
| 694 | ||
| 695 | // const section_exprs = row_exprs[0..section_end]; | |
| 696 | ||
| 697 | // // Null stream for counting the printed length of each expression | |
| 698 | // var line_find_stream = std.io.findByteWriter('\n', std.io.null_writer); | |
| 699 | // var counting_stream = std.io.countingWriter(line_find_stream.writer()); | |
| 700 | // var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, counting_stream.writer()); | |
| 701 | ||
| 702 | // // Calculate size of columns in current section | |
| 703 | // var column_counter: usize = 0; | |
| 704 | // var single_line = true; | |
| 705 | // for (section_exprs) |expr, i| { | |
| 706 | // if (i + 1 < section_exprs.len) { | |
| 707 | // counting_stream.bytes_written = 0; | |
| 708 | // line_find_stream.byte_found = false; | |
| 709 | // try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); | |
| 710 | // const width = @intCast(usize, counting_stream.bytes_written); | |
| 711 | // expr_widths[i] = width; | |
| 712 | // expr_newlines[i] = line_find_stream.byte_found; | |
| 713 | ||
| 714 | // if (!line_find_stream.byte_found) { | |
| 715 | // const column = column_counter % row_size; | |
| 716 | // column_widths[column] = std.math.max(column_widths[column], width); | |
| 717 | ||
| 718 | // const expr_last_token = expr.*.lastToken() + 1; | |
| 719 | // const next_expr = section_exprs[i + 1]; | |
| 720 | // const loc = tree.tokenLocation(tree.token_locs[expr_last_token].start, next_expr.*.firstToken()); | |
| 721 | ||
| 722 | // column_counter += 1; | |
| 723 | ||
| 724 | // if (loc.line != 0) single_line = false; | |
| 725 | // } else { | |
| 726 | // single_line = false; | |
| 727 | // column_counter = 0; | |
| 728 | // } | |
| 729 | // } else { | |
| 730 | // counting_stream.bytes_written = 0; | |
| 731 | // try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); | |
| 732 | // const width = @intCast(usize, counting_stream.bytes_written); | |
| 733 | // expr_widths[i] = width; | |
| 734 | // expr_newlines[i] = line_find_stream.byte_found; | |
| 735 | ||
| 736 | // if (!line_find_stream.byte_found) { | |
| 737 | // const column = column_counter % row_size; | |
| 738 | // column_widths[column] = std.math.max(column_widths[column], width); | |
| 739 | // } | |
| 740 | // break; | |
| 741 | // } | |
| 742 | // } | |
| 743 | ||
| 744 | // // Render exprs in current section | |
| 745 | // column_counter = 0; | |
| 746 | // var last_col_index: usize = row_size - 1; | |
| 747 | // for (section_exprs) |expr, i| { | |
| 748 | // if (i + 1 < section_exprs.len) { | |
| 749 | // const next_expr = section_exprs[i + 1]; | |
| 750 | // try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 751 | ||
| 752 | // const comma = tree.nextToken(expr.*.lastToken()); | |
| 753 | ||
| 754 | // if (column_counter != last_col_index) { | |
| 755 | // if (!expr_newlines[i] and !expr_newlines[i + 1]) { | |
| 756 | // // Neither the current or next expression is multiline | |
| 757 | // try renderToken(ais, tree, comma, Space.Space); // , | |
| 758 | // assert(column_widths[column_counter % row_size] >= expr_widths[i]); | |
| 759 | // const padding = column_widths[column_counter % row_size] - expr_widths[i]; | |
| 760 | // try ais.writer().writeByteNTimes(' ', padding); | |
| 761 | ||
| 762 | // column_counter += 1; | |
| 763 | // continue; | |
| 764 | // } | |
| 765 | // } | |
| 766 | // if (single_line and row_size != 1) { | |
| 767 | // try renderToken(ais, tree, comma, Space.Space); // , | |
| 768 | // continue; | |
| 769 | // } | |
| 770 | ||
| 771 | // column_counter = 0; | |
| 772 | // try renderToken(ais, tree, comma, Space.Newline); // , | |
| 773 | // try renderExtraNewline(tree, ais, next_expr); | |
| 774 | // } else { | |
| 775 | // const maybe_comma = tree.nextToken(expr.*.lastToken()); | |
| 776 | // if (tree.token_tags[maybe_comma] == .Comma) { | |
| 777 | // try renderExpression(allocator, ais, tree, expr, Space.None); // , | |
| 778 | // try renderToken(ais, tree, maybe_comma, Space.Newline); // , | |
| 779 | // } else { | |
| 780 | // try renderExpression(allocator, ais, tree, expr, Space.Comma); // , | |
| 781 | // } | |
| 782 | // } | |
| 783 | // } | |
| 784 | ||
| 785 | // if (expr_index == exprs.len) { | |
| 786 | // break; | |
| 787 | // } | |
| 788 | // } | |
| 789 | // } | |
| 790 | ||
| 791 | // return renderToken(ais, tree, rtoken, space); | |
| 792 | // } | |
| 793 | ||
| 794 | // // Single line | |
| 795 | // try renderToken(ais, tree, lbrace, Space.Space); | |
| 796 | // for (exprs) |expr, i| { | |
| 797 | // if (i + 1 < exprs.len) { | |
| 798 | // const next_expr = exprs[i + 1]; | |
| 799 | // try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 800 | // const comma = tree.nextToken(expr.*.lastToken()); | |
| 801 | // try renderToken(ais, tree, comma, Space.Space); // , | |
| 802 | // } else { | |
| 803 | // try renderExpression(allocator, ais, tree, expr, Space.Space); | |
| 804 | // } | |
| 805 | // } | |
| 806 | ||
| 807 | // return renderToken(ais, tree, rtoken, space); | |
| 808 | //}, | |
| 809 | ||
| 810 | //.StructInitializer, .StructInitializerDot => { | |
| 811 | // var rtoken: ast.TokenIndex = undefined; | |
| 812 | // var field_inits: []ast.Node.Index = undefined; | |
| 813 | // const lhs: union(enum) { dot: ast.TokenIndex, node: ast.Node.Index } = switch (base.tag) { | |
| 814 | // .StructInitializerDot => blk: { | |
| 815 | // const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base); | |
| 816 | // rtoken = casted.rtoken; | |
| 817 | // field_inits = casted.list(); | |
| 818 | // break :blk .{ .dot = casted.dot }; | |
| 819 | // }, | |
| 820 | // .StructInitializer => blk: { | |
| 821 | // const casted = @fieldParentPtr(ast.Node.StructInitializer, "base", base); | |
| 822 | // rtoken = casted.rtoken; | |
| 823 | // field_inits = casted.list(); | |
| 824 | // break :blk .{ .node = casted.lhs }; | |
| 825 | // }, | |
| 826 | // else => unreachable, | |
| 827 | // }; | |
| 828 | ||
| 829 | // const lbrace = switch (lhs) { | |
| 830 | // .dot => |dot| tree.nextToken(dot), | |
| 831 | // .node => |node| tree.nextToken(node.lastToken()), | |
| 832 | // }; | |
| 833 | ||
| 834 | // if (field_inits.len == 0) { | |
| 835 | // switch (lhs) { | |
| 836 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | |
| 837 | // .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 838 | // } | |
| 839 | ||
| 840 | // { | |
| 841 | // ais.pushIndentNextLine(); | |
| 842 | // defer ais.popIndent(); | |
| 843 | // try renderToken(ais, tree, lbrace, Space.None); | |
| 844 | // } | |
| 845 | ||
| 846 | // return renderToken(ais, tree, rtoken, space); | |
| 847 | // } | |
| 848 | ||
| 849 | // const src_has_trailing_comma = blk: { | |
| 850 | // const maybe_comma = tree.prevToken(rtoken); | |
| 851 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 852 | // }; | |
| 853 | ||
| 854 | // const src_same_line = blk: { | |
| 855 | // const loc = tree.tokenLocation(tree.token_locs[lbrace].end, rtoken); | |
| 856 | // break :blk loc.line == 0; | |
| 857 | // }; | |
| 858 | ||
| 859 | // const expr_outputs_one_line = blk: { | |
| 860 | // // render field expressions until a LF is found | |
| 861 | // for (field_inits) |field_init| { | |
| 862 | // var find_stream = std.io.findByteWriter('\n', std.io.null_writer); | |
| 863 | // var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, find_stream.writer()); | |
| 864 | ||
| 865 | // try renderExpression(allocator, &auto_indenting_stream, tree, field_init, Space.None); | |
| 866 | // if (find_stream.byte_found) break :blk false; | |
| 867 | // } | |
| 868 | // break :blk true; | |
| 869 | // }; | |
| 870 | ||
| 871 | // if (field_inits.len == 1) blk: { | |
| 872 | // if (field_inits[0].cast(ast.Node.FieldInitializer)) |field_init| { | |
| 873 | // switch (field_init.expr.tag) { | |
| 874 | // .StructInitializer, | |
| 875 | // .StructInitializerDot, | |
| 876 | // => break :blk, | |
| 877 | // else => {}, | |
| 878 | // } | |
| 879 | // } | |
| 880 | ||
| 881 | // // if the expression outputs to multiline, make this struct multiline | |
| 882 | // if (!expr_outputs_one_line or src_has_trailing_comma) { | |
| 883 | // break :blk; | |
| 884 | // } | |
| 885 | ||
| 886 | // switch (lhs) { | |
| 887 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | |
| 888 | // .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 889 | // } | |
| 890 | // try renderToken(ais, tree, lbrace, Space.Space); | |
| 891 | // try renderExpression(allocator, ais, tree, field_inits[0], Space.Space); | |
| 892 | // return renderToken(ais, tree, rtoken, space); | |
| 893 | // } | |
| 894 | ||
| 895 | // if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) { | |
| 896 | // // render all on one line, no trailing comma | |
| 897 | // switch (lhs) { | |
| 898 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | |
| 899 | // .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 900 | // } | |
| 901 | // try renderToken(ais, tree, lbrace, Space.Space); | |
| 902 | ||
| 903 | // for (field_inits) |field_init, i| { | |
| 904 | // if (i + 1 < field_inits.len) { | |
| 905 | // try renderExpression(allocator, ais, tree, field_init, Space.None); | |
| 906 | ||
| 907 | // const comma = tree.nextToken(field_init.lastToken()); | |
| 908 | // try renderToken(ais, tree, comma, Space.Space); | |
| 909 | // } else { | |
| 910 | // try renderExpression(allocator, ais, tree, field_init, Space.Space); | |
| 911 | // } | |
| 912 | // } | |
| 913 | ||
| 914 | // return renderToken(ais, tree, rtoken, space); | |
| 915 | // } | |
| 916 | ||
| 917 | // { | |
| 918 | // switch (lhs) { | |
| 919 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | |
| 920 | // .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | |
| 921 | // } | |
| 922 | ||
| 923 | // ais.pushIndentNextLine(); | |
| 924 | // defer ais.popIndent(); | |
| 925 | ||
| 926 | // try renderToken(ais, tree, lbrace, Space.Newline); | |
| 927 | ||
| 928 | // for (field_inits) |field_init, i| { | |
| 929 | // if (i + 1 < field_inits.len) { | |
| 930 | // const next_field_init = field_inits[i + 1]; | |
| 931 | // try renderExpression(allocator, ais, tree, field_init, Space.None); | |
| 932 | ||
| 933 | // const comma = tree.nextToken(field_init.lastToken()); | |
| 934 | // try renderToken(ais, tree, comma, Space.Newline); | |
| 935 | ||
| 936 | // try renderExtraNewline(tree, ais, next_field_init); | |
| 937 | // } else { | |
| 938 | // try renderExpression(allocator, ais, tree, field_init, Space.Comma); | |
| 939 | // } | |
| 940 | // } | |
| 941 | // } | |
| 942 | ||
| 943 | // return renderToken(ais, tree, rtoken, space); | |
| 944 | //}, | |
| 945 | ||
| 946 | //.Call => { | |
| 947 | // const call = @fieldParentPtr(ast.Node.Call, "base", base); | |
| 948 | // if (call.async_token) |async_token| { | |
| 949 | // try renderToken(ais, tree, async_token, Space.Space); | |
| 950 | // } | |
| 951 | ||
| 952 | // try renderExpression(allocator, ais, tree, call.lhs, Space.None); | |
| 953 | ||
| 954 | // const lparen = tree.nextToken(call.lhs.lastToken()); | |
| 955 | ||
| 956 | // if (call.params_len == 0) { | |
| 957 | // try renderToken(ais, tree, lparen, Space.None); | |
| 958 | // return renderToken(ais, tree, call.rtoken, space); | |
| 959 | // } | |
| 960 | ||
| 961 | // const src_has_trailing_comma = blk: { | |
| 962 | // const maybe_comma = tree.prevToken(call.rtoken); | |
| 963 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 964 | // }; | |
| 965 | ||
| 966 | // if (src_has_trailing_comma) { | |
| 967 | // { | |
| 968 | // ais.pushIndent(); | |
| 969 | // defer ais.popIndent(); | |
| 970 | ||
| 971 | // try renderToken(ais, tree, lparen, Space.Newline); // ( | |
| 972 | // const params = call.params(); | |
| 973 | // for (params) |param_node, i| { | |
| 974 | // if (i + 1 < params.len) { | |
| 975 | // const next_node = params[i + 1]; | |
| 976 | // try renderExpression(allocator, ais, tree, param_node, Space.None); | |
| 977 | ||
| 978 | // // Unindent the comma for multiline string literals | |
| 979 | // const maybe_multiline_string = param_node.firstToken(); | |
| 980 | // const is_multiline_string = tree.token_tags[maybe_multiline_string] == .MultilineStringLiteralLine; | |
| 981 | // if (is_multiline_string) ais.popIndent(); | |
| 982 | // defer if (is_multiline_string) ais.pushIndent(); | |
| 983 | ||
| 984 | // const comma = tree.nextToken(param_node.lastToken()); | |
| 985 | // try renderToken(ais, tree, comma, Space.Newline); // , | |
| 986 | // try renderExtraNewline(tree, ais, next_node); | |
| 987 | // } else { | |
| 988 | // try renderExpression(allocator, ais, tree, param_node, Space.Comma); | |
| 989 | // } | |
| 990 | // } | |
| 991 | // } | |
| 992 | // return renderToken(ais, tree, call.rtoken, space); | |
| 993 | // } | |
| 994 | ||
| 995 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 996 | ||
| 997 | // const params = call.params(); | |
| 998 | // for (params) |param_node, i| { | |
| 999 | // const maybe_comment = param_node.firstToken() - 1; | |
| 1000 | // const maybe_multiline_string = param_node.firstToken(); | |
| 1001 | // if (tree.token_tags[maybe_multiline_string] == .MultilineStringLiteralLine or tree.token_tags[maybe_comment] == .LineComment) { | |
| 1002 | // ais.pushIndentOneShot(); | |
| 1003 | // } | |
| 1004 | ||
| 1005 | // try renderExpression(allocator, ais, tree, param_node, Space.None); | |
| 1006 | ||
| 1007 | // if (i + 1 < params.len) { | |
| 1008 | // const comma = tree.nextToken(param_node.lastToken()); | |
| 1009 | // try renderToken(ais, tree, comma, Space.Space); | |
| 1010 | // } | |
| 1011 | // } | |
| 1012 | // return renderToken(ais, tree, call.rtoken, space); // ) | |
| 1013 | //}, | |
| 1014 | ||
| 1015 | //.ArrayAccess => { | |
| 1016 | // const suffix_op = base.castTag(.ArrayAccess).?; | |
| 1017 | ||
| 1018 | // const lbracket = tree.nextToken(suffix_op.lhs.lastToken()); | |
| 1019 | // const rbracket = tree.nextToken(suffix_op.index_expr.lastToken()); | |
| 1020 | ||
| 1021 | // try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1022 | // try renderToken(ais, tree, lbracket, Space.None); // [ | |
| 1023 | ||
| 1024 | // const starts_with_comment = tree.token_tags[lbracket + 1] == .LineComment; | |
| 1025 | // const ends_with_comment = tree.token_tags[rbracket - 1] == .LineComment; | |
| 1026 | // { | |
| 1027 | // const new_space = if (ends_with_comment) Space.Newline else Space.None; | |
| 1028 | ||
| 1029 | // ais.pushIndent(); | |
| 1030 | // defer ais.popIndent(); | |
| 1031 | // try renderExpression(allocator, ais, tree, suffix_op.index_expr, new_space); | |
| 1032 | // } | |
| 1033 | // if (starts_with_comment) try ais.maybeInsertNewline(); | |
| 1034 | // return renderToken(ais, tree, rbracket, space); // ] | |
| 1035 | //}, | |
| 1036 | ||
| 1037 | //.Slice => { | |
| 1038 | // const suffix_op = base.castTag(.Slice).?; | |
| 1039 | // try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1040 | ||
| 1041 | // const lbracket = tree.prevToken(suffix_op.start.firstToken()); | |
| 1042 | // const dotdot = tree.nextToken(suffix_op.start.lastToken()); | |
| 1043 | ||
| 1044 | // const after_start_space_bool = nodeCausesSliceOpSpace(suffix_op.start) or | |
| 1045 | // (if (suffix_op.end) |end| nodeCausesSliceOpSpace(end) else false); | |
| 1046 | // const after_start_space = if (after_start_space_bool) Space.Space else Space.None; | |
| 1047 | // const after_op_space = if (suffix_op.end != null) after_start_space else Space.None; | |
| 1048 | ||
| 1049 | // try renderToken(ais, tree, lbracket, Space.None); // [ | |
| 1050 | // try renderExpression(allocator, ais, tree, suffix_op.start, after_start_space); | |
| 1051 | // try renderToken(ais, tree, dotdot, after_op_space); // .. | |
| 1052 | // if (suffix_op.end) |end| { | |
| 1053 | // const after_end_space = if (suffix_op.sentinel != null) Space.Space else Space.None; | |
| 1054 | // try renderExpression(allocator, ais, tree, end, after_end_space); | |
| 1055 | // } | |
| 1056 | // if (suffix_op.sentinel) |sentinel| { | |
| 1057 | // const colon = tree.prevToken(sentinel.firstToken()); | |
| 1058 | // try renderToken(ais, tree, colon, Space.None); // : | |
| 1059 | // try renderExpression(allocator, ais, tree, sentinel, Space.None); | |
| 1060 | // } | |
| 1061 | // return renderToken(ais, tree, suffix_op.rtoken, space); // ] | |
| 1062 | //}, | |
| 1063 | ||
| 1064 | //.Deref => { | |
| 1065 | // const suffix_op = base.castTag(.Deref).?; | |
| 1066 | ||
| 1067 | // try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1068 | // return renderToken(ais, tree, suffix_op.rtoken, space); // .* | |
| 1069 | //}, | |
| 1070 | //.UnwrapOptional => { | |
| 1071 | // const suffix_op = base.castTag(.UnwrapOptional).?; | |
| 1072 | ||
| 1073 | // try renderExpression(allocator, ais, tree, suffix_op.lhs, Space.None); | |
| 1074 | // try renderToken(ais, tree, tree.prevToken(suffix_op.rtoken), Space.None); // . | |
| 1075 | // return renderToken(ais, tree, suffix_op.rtoken, space); // ? | |
| 1076 | //}, | |
| 1077 | ||
| 1078 | //.Break => { | |
| 1079 | // const flow_expr = base.castTag(.Break).?; | |
| 1080 | // const maybe_rhs = flow_expr.getRHS(); | |
| 1081 | // const maybe_label = flow_expr.getLabel(); | |
| 1082 | ||
| 1083 | // if (maybe_label == null and maybe_rhs == null) { | |
| 1084 | // return renderToken(ais, tree, flow_expr.ltoken, space); // break | |
| 1085 | // } | |
| 1086 | ||
| 1087 | // try renderToken(ais, tree, flow_expr.ltoken, Space.Space); // break | |
| 1088 | // if (maybe_label) |label| { | |
| 1089 | // const colon = tree.nextToken(flow_expr.ltoken); | |
| 1090 | // try renderToken(ais, tree, colon, Space.None); // : | |
| 1091 | ||
| 1092 | // if (maybe_rhs == null) { | |
| 1093 | // return renderToken(ais, tree, label, space); // label | |
| 1094 | // } | |
| 1095 | // try renderToken(ais, tree, label, Space.Space); // label | |
| 1096 | // } | |
| 1097 | // return renderExpression(allocator, ais, tree, maybe_rhs.?, space); | |
| 1098 | //}, | |
| 1099 | ||
| 1100 | //.Continue => { | |
| 1101 | // const flow_expr = base.castTag(.Continue).?; | |
| 1102 | // if (flow_expr.getLabel()) |label| { | |
| 1103 | // try renderToken(ais, tree, flow_expr.ltoken, Space.Space); // continue | |
| 1104 | // const colon = tree.nextToken(flow_expr.ltoken); | |
| 1105 | // try renderToken(ais, tree, colon, Space.None); // : | |
| 1106 | // return renderToken(ais, tree, label, space); // label | |
| 1107 | // } else { | |
| 1108 | // return renderToken(ais, tree, flow_expr.ltoken, space); // continue | |
| 1109 | // } | |
| 1110 | //}, | |
| 1111 | ||
| 1112 | //.Return => { | |
| 1113 | // const flow_expr = base.castTag(.Return).?; | |
| 1114 | // if (flow_expr.getRHS()) |rhs| { | |
| 1115 | // try renderToken(ais, tree, flow_expr.ltoken, Space.Space); | |
| 1116 | // return renderExpression(allocator, ais, tree, rhs, space); | |
| 1117 | // } else { | |
| 1118 | // return renderToken(ais, tree, flow_expr.ltoken, space); | |
| 1119 | // } | |
| 1120 | //}, | |
| 1121 | ||
| 1122 | //.Payload => { | |
| 1123 | // const payload = @fieldParentPtr(ast.Node.Payload, "base", base); | |
| 1124 | ||
| 1125 | // try renderToken(ais, tree, payload.lpipe, Space.None); | |
| 1126 | // try renderExpression(allocator, ais, tree, payload.error_symbol, Space.None); | |
| 1127 | // return renderToken(ais, tree, payload.rpipe, space); | |
| 1128 | //}, | |
| 1129 | ||
| 1130 | //.PointerPayload => { | |
| 1131 | // const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base); | |
| 1132 | ||
| 1133 | // try renderToken(ais, tree, payload.lpipe, Space.None); | |
| 1134 | // if (payload.ptr_token) |ptr_token| { | |
| 1135 | // try renderToken(ais, tree, ptr_token, Space.None); | |
| 1136 | // } | |
| 1137 | // try renderExpression(allocator, ais, tree, payload.value_symbol, Space.None); | |
| 1138 | // return renderToken(ais, tree, payload.rpipe, space); | |
| 1139 | //}, | |
| 1140 | ||
| 1141 | //.PointerIndexPayload => { | |
| 1142 | // const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base); | |
| 1143 | ||
| 1144 | // try renderToken(ais, tree, payload.lpipe, Space.None); | |
| 1145 | // if (payload.ptr_token) |ptr_token| { | |
| 1146 | // try renderToken(ais, tree, ptr_token, Space.None); | |
| 1147 | // } | |
| 1148 | // try renderExpression(allocator, ais, tree, payload.value_symbol, Space.None); | |
| 1149 | ||
| 1150 | // if (payload.index_symbol) |index_symbol| { | |
| 1151 | // const comma = tree.nextToken(payload.value_symbol.lastToken()); | |
| 1152 | ||
| 1153 | // try renderToken(ais, tree, comma, Space.Space); | |
| 1154 | // try renderExpression(allocator, ais, tree, index_symbol, Space.None); | |
| 1155 | // } | |
| 1156 | ||
| 1157 | // return renderToken(ais, tree, payload.rpipe, space); | |
| 1158 | //}, | |
| 1159 | ||
| 1160 | //.GroupedExpression => { | |
| 1161 | // const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base); | |
| 1162 | ||
| 1163 | // try renderToken(ais, tree, grouped_expr.lparen, Space.None); | |
| 1164 | // { | |
| 1165 | // ais.pushIndentOneShot(); | |
| 1166 | // try renderExpression(allocator, ais, tree, grouped_expr.expr, Space.None); | |
| 1167 | // } | |
| 1168 | // return renderToken(ais, tree, grouped_expr.rparen, space); | |
| 1169 | //}, | |
| 1170 | ||
| 1171 | //.FieldInitializer => { | |
| 1172 | // const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base); | |
| 1173 | ||
| 1174 | // try renderToken(ais, tree, field_init.period_token, Space.None); // . | |
| 1175 | // try renderToken(ais, tree, field_init.name_token, Space.Space); // name | |
| 1176 | // try renderToken(ais, tree, tree.nextToken(field_init.name_token), Space.Space); // = | |
| 1177 | // return renderExpression(allocator, ais, tree, field_init.expr, space); | |
| 1178 | //}, | |
| 1179 | ||
| 1180 | //.ContainerDecl => { | |
| 1181 | // const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base); | |
| 1182 | ||
| 1183 | // if (container_decl.layout_token) |layout_token| { | |
| 1184 | // try renderToken(ais, tree, layout_token, Space.Space); | |
| 1185 | // } | |
| 1186 | ||
| 1187 | // switch (container_decl.init_arg_expr) { | |
| 1188 | // .None => { | |
| 1189 | // try renderToken(ais, tree, container_decl.kind_token, Space.Space); // union | |
| 1190 | // }, | |
| 1191 | // .Enum => |enum_tag_type| { | |
| 1192 | // try renderToken(ais, tree, container_decl.kind_token, Space.None); // union | |
| 1193 | ||
| 1194 | // const lparen = tree.nextToken(container_decl.kind_token); | |
| 1195 | // const enum_token = tree.nextToken(lparen); | |
| 1196 | ||
| 1197 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1198 | // try renderToken(ais, tree, enum_token, Space.None); // enum | |
| 1199 | ||
| 1200 | // if (enum_tag_type) |expr| { | |
| 1201 | // try renderToken(ais, tree, tree.nextToken(enum_token), Space.None); // ( | |
| 1202 | // try renderExpression(allocator, ais, tree, expr, Space.None); | |
| 1203 | ||
| 1204 | // const rparen = tree.nextToken(expr.lastToken()); | |
| 1205 | // try renderToken(ais, tree, rparen, Space.None); // ) | |
| 1206 | // try renderToken(ais, tree, tree.nextToken(rparen), Space.Space); // ) | |
| 1207 | // } else { | |
| 1208 | // try renderToken(ais, tree, tree.nextToken(enum_token), Space.Space); // ) | |
| 1209 | // } | |
| 1210 | // }, | |
| 1211 | // .Type => |type_expr| { | |
| 1212 | // try renderToken(ais, tree, container_decl.kind_token, Space.None); // union | |
| 1213 | ||
| 1214 | // const lparen = tree.nextToken(container_decl.kind_token); | |
| 1215 | // const rparen = tree.nextToken(type_expr.lastToken()); | |
| 1216 | ||
| 1217 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1218 | // try renderExpression(allocator, ais, tree, type_expr, Space.None); | |
| 1219 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 1220 | // }, | |
| 1221 | // } | |
| 1222 | ||
| 1223 | // if (container_decl.fields_and_decls_len == 0) { | |
| 1224 | // { | |
| 1225 | // ais.pushIndentNextLine(); | |
| 1226 | // defer ais.popIndent(); | |
| 1227 | // try renderToken(ais, tree, container_decl.lbrace_token, Space.None); // { | |
| 1228 | // } | |
| 1229 | // return renderToken(ais, tree, container_decl.rbrace_token, space); // } | |
| 1230 | // } | |
| 1231 | ||
| 1232 | // const src_has_trailing_comma = blk: { | |
| 1233 | // var maybe_comma = tree.prevToken(container_decl.lastToken()); | |
| 1234 | // // Doc comments for a field may also appear after the comma, eg. | |
| 1235 | // // field_name: T, // comment attached to field_name | |
| 1236 | // if (tree.token_tags[maybe_comma] == .DocComment) | |
| 1237 | // maybe_comma = tree.prevToken(maybe_comma); | |
| 1238 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 1239 | // }; | |
| 1240 | ||
| 1241 | // const fields_and_decls = container_decl.fieldsAndDecls(); | |
| 1242 | ||
| 1243 | // // Check if the first declaration and the { are on the same line | |
| 1244 | // const src_has_newline = !tree.tokensOnSameLine( | |
| 1245 | // container_decl.lbrace_token, | |
| 1246 | // fields_and_decls[0].firstToken(), | |
| 1247 | // ); | |
| 1248 | ||
| 1249 | // // We can only print all the elements in-line if all the | |
| 1250 | // // declarations inside are fields | |
| 1251 | // const src_has_only_fields = blk: { | |
| 1252 | // for (fields_and_decls) |decl| { | |
| 1253 | // if (decl.tag != .ContainerField) break :blk false; | |
| 1254 | // } | |
| 1255 | // break :blk true; | |
| 1256 | // }; | |
| 1257 | ||
| 1258 | // if (src_has_trailing_comma or !src_has_only_fields) { | |
| 1259 | // // One declaration per line | |
| 1260 | // ais.pushIndentNextLine(); | |
| 1261 | // defer ais.popIndent(); | |
| 1262 | // try renderToken(ais, tree, container_decl.lbrace_token, .Newline); // { | |
| 1263 | ||
| 1264 | // for (fields_and_decls) |decl, i| { | |
| 1265 | // try renderContainerDecl(allocator, ais, tree, decl, .Newline); | |
| 1266 | ||
| 1267 | // if (i + 1 < fields_and_decls.len) { | |
| 1268 | // try renderExtraNewline(tree, ais, fields_and_decls[i + 1]); | |
| 1269 | // } | |
| 1270 | // } | |
| 1271 | // } else if (src_has_newline) { | |
| 1272 | // // All the declarations on the same line, but place the items on | |
| 1273 | // // their own line | |
| 1274 | // try renderToken(ais, tree, container_decl.lbrace_token, .Newline); // { | |
| 1275 | ||
| 1276 | // ais.pushIndent(); | |
| 1277 | // defer ais.popIndent(); | |
| 1278 | ||
| 1279 | // for (fields_and_decls) |decl, i| { | |
| 1280 | // const space_after_decl: Space = if (i + 1 >= fields_and_decls.len) .Newline else .Space; | |
| 1281 | // try renderContainerDecl(allocator, ais, tree, decl, space_after_decl); | |
| 1282 | // } | |
| 1283 | // } else { | |
| 1284 | // // All the declarations on the same line | |
| 1285 | // try renderToken(ais, tree, container_decl.lbrace_token, .Space); // { | |
| 1286 | ||
| 1287 | // for (fields_and_decls) |decl| { | |
| 1288 | // try renderContainerDecl(allocator, ais, tree, decl, .Space); | |
| 1289 | // } | |
| 1290 | // } | |
| 1291 | ||
| 1292 | // return renderToken(ais, tree, container_decl.rbrace_token, space); // } | |
| 1293 | //}, | |
| 1294 | ||
| 1295 | //.ErrorSetDecl => { | |
| 1296 | // const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base); | |
| 1297 | ||
| 1298 | // const lbrace = tree.nextToken(err_set_decl.error_token); | |
| 1299 | ||
| 1300 | // if (err_set_decl.decls_len == 0) { | |
| 1301 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); | |
| 1302 | // try renderToken(ais, tree, lbrace, Space.None); | |
| 1303 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); | |
| 1304 | // } | |
| 1305 | ||
| 1306 | // if (err_set_decl.decls_len == 1) blk: { | |
| 1307 | // const node = err_set_decl.decls()[0]; | |
| 1308 | ||
| 1309 | // // if there are any doc comments or same line comments | |
| 1310 | // // don't try to put it all on one line | |
| 1311 | // if (node.cast(ast.Node.ErrorTag)) |tag| { | |
| 1312 | // if (tag.doc_comments != null) break :blk; | |
| 1313 | // } else { | |
| 1314 | // break :blk; | |
| 1315 | // } | |
| 1316 | ||
| 1317 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error | |
| 1318 | // try renderToken(ais, tree, lbrace, Space.None); // { | |
| 1319 | // try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1320 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // } | |
| 1321 | // } | |
| 1322 | ||
| 1323 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error | |
| 1324 | ||
| 1325 | // const src_has_trailing_comma = blk: { | |
| 1326 | // const maybe_comma = tree.prevToken(err_set_decl.rbrace_token); | |
| 1327 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 1328 | // }; | |
| 1329 | ||
| 1330 | // if (src_has_trailing_comma) { | |
| 1331 | // { | |
| 1332 | // ais.pushIndent(); | |
| 1333 | // defer ais.popIndent(); | |
| 1334 | ||
| 1335 | // try renderToken(ais, tree, lbrace, Space.Newline); // { | |
| 1336 | // const decls = err_set_decl.decls(); | |
| 1337 | // for (decls) |node, i| { | |
| 1338 | // if (i + 1 < decls.len) { | |
| 1339 | // try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1340 | // try renderToken(ais, tree, tree.nextToken(node.lastToken()), Space.Newline); // , | |
| 1341 | ||
| 1342 | // try renderExtraNewline(tree, ais, decls[i + 1]); | |
| 1343 | // } else { | |
| 1344 | // try renderExpression(allocator, ais, tree, node, Space.Comma); | |
| 1345 | // } | |
| 1346 | // } | |
| 1347 | // } | |
| 1348 | ||
| 1349 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // } | |
| 1350 | // } else { | |
| 1351 | // try renderToken(ais, tree, lbrace, Space.Space); // { | |
| 1352 | ||
| 1353 | // const decls = err_set_decl.decls(); | |
| 1354 | // for (decls) |node, i| { | |
| 1355 | // if (i + 1 < decls.len) { | |
| 1356 | // try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1357 | ||
| 1358 | // const comma_token = tree.nextToken(node.lastToken()); | |
| 1359 | // assert(tree.token_tags[comma_token] == .Comma); | |
| 1360 | // try renderToken(ais, tree, comma_token, Space.Space); // , | |
| 1361 | // try renderExtraNewline(tree, ais, decls[i + 1]); | |
| 1362 | // } else { | |
| 1363 | // try renderExpression(allocator, ais, tree, node, Space.Space); | |
| 1364 | // } | |
| 1365 | // } | |
| 1366 | ||
| 1367 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // } | |
| 1368 | // } | |
| 1369 | //}, | |
| 1370 | ||
| 1371 | //.ErrorTag => { | |
| 1372 | // const tag = @fieldParentPtr(ast.Node.ErrorTag, "base", base); | |
| 1373 | ||
| 1374 | // try renderDocComments(tree, ais, tag, tag.doc_comments); | |
| 1375 | // return renderToken(ais, tree, tag.name_token, space); // name | |
| 1376 | //}, | |
| 1377 | ||
| 1378 | //.MultilineStringLiteral => { | |
| 1379 | // const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base); | |
| 1380 | ||
| 1381 | // { | |
| 1382 | // const locked_indents = ais.lockOneShotIndent(); | |
| 1383 | // defer { | |
| 1384 | // var i: u8 = 0; | |
| 1385 | // while (i < locked_indents) : (i += 1) ais.popIndent(); | |
| 1386 | // } | |
| 1387 | // try ais.maybeInsertNewline(); | |
| 1388 | ||
| 1389 | // for (multiline_str_literal.lines()) |t| try renderToken(ais, tree, t, Space.None); | |
| 1390 | // } | |
| 1391 | //}, | |
| 1392 | ||
| 1393 | //.BuiltinCall => { | |
| 1394 | // const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base); | |
| 1395 | ||
| 1396 | // // TODO remove after 0.7.0 release | |
| 1397 | // if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@OpaqueType")) | |
| 1398 | // return ais.writer().writeAll("opaque {}"); | |
| 1399 | ||
| 1400 | // // TODO remove after 0.7.0 release | |
| 1401 | // { | |
| 1402 | // const params = builtin_call.paramsConst(); | |
| 1403 | // if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@Type") and | |
| 1404 | // params.len == 1) | |
| 1405 | // { | |
| 1406 | // if (params[0].castTag(.EnumLiteral)) |enum_literal| | |
| 1407 | // if (mem.eql(u8, tree.tokenSlice(enum_literal.name), "Opaque")) | |
| 1408 | // return ais.writer().writeAll("opaque {}"); | |
| 1409 | // } | |
| 1410 | // } | |
| 1411 | ||
| 1412 | // try renderToken(ais, tree, builtin_call.builtin_token, Space.None); // @name | |
| 1413 | ||
| 1414 | // const src_params_trailing_comma = blk: { | |
| 1415 | // if (builtin_call.params_len == 0) break :blk false; | |
| 1416 | // const last_node = builtin_call.params()[builtin_call.params_len - 1]; | |
| 1417 | // const maybe_comma = tree.nextToken(last_node.lastToken()); | |
| 1418 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 1419 | // }; | |
| 1420 | ||
| 1421 | // const lparen = tree.nextToken(builtin_call.builtin_token); | |
| 1422 | ||
| 1423 | // if (!src_params_trailing_comma) { | |
| 1424 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1425 | ||
| 1426 | // // render all on one line, no trailing comma | |
| 1427 | // const params = builtin_call.params(); | |
| 1428 | // for (params) |param_node, i| { | |
| 1429 | // const maybe_comment = param_node.firstToken() - 1; | |
| 1430 | // if (param_node.*.tag == .MultilineStringLiteral or tree.token_tags[maybe_comment] == .LineComment) { | |
| 1431 | // ais.pushIndentOneShot(); | |
| 1432 | // } | |
| 1433 | // try renderExpression(allocator, ais, tree, param_node, Space.None); | |
| 1434 | ||
| 1435 | // if (i + 1 < params.len) { | |
| 1436 | // const comma_token = tree.nextToken(param_node.lastToken()); | |
| 1437 | // try renderToken(ais, tree, comma_token, Space.Space); // , | |
| 1438 | // } | |
| 1439 | // } | |
| 1440 | // } else { | |
| 1441 | // // one param per line | |
| 1442 | // ais.pushIndent(); | |
| 1443 | // defer ais.popIndent(); | |
| 1444 | // try renderToken(ais, tree, lparen, Space.Newline); // ( | |
| 1445 | ||
| 1446 | // for (builtin_call.params()) |param_node| { | |
| 1447 | // try renderExpression(allocator, ais, tree, param_node, Space.Comma); | |
| 1448 | // } | |
| 1449 | // } | |
| 1450 | ||
| 1451 | // return renderToken(ais, tree, builtin_call.rparen_token, space); // ) | |
| 1452 | //}, | |
| 1453 | ||
| 1454 | //.FnProto => { | |
| 1455 | // const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", base); | |
| 1456 | ||
| 1457 | // if (fn_proto.getVisibToken()) |visib_token_index| { | |
| 1458 | // const visib_token = tree.token_tags[visib_token_index]; | |
| 1459 | // assert(visib_token == .Keyword_pub or visib_token == .Keyword_export); | |
| 1460 | ||
| 1461 | // try renderToken(ais, tree, visib_token_index, Space.Space); // pub | |
| 1462 | // } | |
| 1463 | ||
| 1464 | // if (fn_proto.getExternExportInlineToken()) |extern_export_inline_token| { | |
| 1465 | // if (fn_proto.getIsExternPrototype() == null) | |
| 1466 | // try renderToken(ais, tree, extern_export_inline_token, Space.Space); // extern/export/inline | |
| 1467 | // } | |
| 1468 | ||
| 1469 | // if (fn_proto.getLibName()) |lib_name| { | |
| 1470 | // try renderExpression(allocator, ais, tree, lib_name, Space.Space); | |
| 1471 | // } | |
| 1472 | ||
| 1473 | // const lparen = if (fn_proto.getNameToken()) |name_token| blk: { | |
| 1474 | // try renderToken(ais, tree, fn_proto.fn_token, Space.Space); // fn | |
| 1475 | // try renderToken(ais, tree, name_token, Space.None); // name | |
| 1476 | // break :blk tree.nextToken(name_token); | |
| 1477 | // } else blk: { | |
| 1478 | // try renderToken(ais, tree, fn_proto.fn_token, Space.Space); // fn | |
| 1479 | // break :blk tree.nextToken(fn_proto.fn_token); | |
| 1480 | // }; | |
| 1481 | // assert(tree.token_tags[lparen] == .LParen); | |
| 1482 | ||
| 1483 | // const rparen = tree.prevToken( | |
| 1484 | // // the first token for the annotation expressions is the left | |
| 1485 | // // parenthesis, hence the need for two prevToken | |
| 1486 | // if (fn_proto.getAlignExpr()) |align_expr| | |
| 1487 | // tree.prevToken(tree.prevToken(align_expr.firstToken())) | |
| 1488 | // else if (fn_proto.getSectionExpr()) |section_expr| | |
| 1489 | // tree.prevToken(tree.prevToken(section_expr.firstToken())) | |
| 1490 | // else if (fn_proto.getCallconvExpr()) |callconv_expr| | |
| 1491 | // tree.prevToken(tree.prevToken(callconv_expr.firstToken())) | |
| 1492 | // else switch (fn_proto.return_type) { | |
| 1493 | // .Explicit => |node| node.firstToken(), | |
| 1494 | // .InferErrorSet => |node| tree.prevToken(node.firstToken()), | |
| 1495 | // .Invalid => unreachable, | |
| 1496 | // }, | |
| 1497 | // ); | |
| 1498 | // assert(tree.token_tags[rparen] == .RParen); | |
| 1499 | ||
| 1500 | // const src_params_trailing_comma = blk: { | |
| 1501 | // const maybe_comma = tree.token_tags[rparen - 1]; | |
| 1502 | // break :blk maybe_comma == .Comma or maybe_comma == .LineComment; | |
| 1503 | // }; | |
| 1504 | ||
| 1505 | // if (!src_params_trailing_comma) { | |
| 1506 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1507 | ||
| 1508 | // // render all on one line, no trailing comma | |
| 1509 | // for (fn_proto.params()) |param_decl, i| { | |
| 1510 | // try renderParamDecl(allocator, ais, tree, param_decl, Space.None); | |
| 1511 | ||
| 1512 | // if (i + 1 < fn_proto.params_len or fn_proto.getVarArgsToken() != null) { | |
| 1513 | // const comma = tree.nextToken(param_decl.lastToken()); | |
| 1514 | // try renderToken(ais, tree, comma, Space.Space); // , | |
| 1515 | // } | |
| 1516 | // } | |
| 1517 | // if (fn_proto.getVarArgsToken()) |var_args_token| { | |
| 1518 | // try renderToken(ais, tree, var_args_token, Space.None); | |
| 1519 | // } | |
| 1520 | // } else { | |
| 1521 | // // one param per line | |
| 1522 | // ais.pushIndent(); | |
| 1523 | // defer ais.popIndent(); | |
| 1524 | // try renderToken(ais, tree, lparen, Space.Newline); // ( | |
| 1525 | ||
| 1526 | // for (fn_proto.params()) |param_decl| { | |
| 1527 | // try renderParamDecl(allocator, ais, tree, param_decl, Space.Comma); | |
| 1528 | // } | |
| 1529 | // if (fn_proto.getVarArgsToken()) |var_args_token| { | |
| 1530 | // try renderToken(ais, tree, var_args_token, Space.Comma); | |
| 1531 | // } | |
| 1532 | // } | |
| 1533 | ||
| 1534 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 1535 | ||
| 1536 | // if (fn_proto.getAlignExpr()) |align_expr| { | |
| 1537 | // const align_rparen = tree.nextToken(align_expr.lastToken()); | |
| 1538 | // const align_lparen = tree.prevToken(align_expr.firstToken()); | |
| 1539 | // const align_kw = tree.prevToken(align_lparen); | |
| 1540 | ||
| 1541 | // try renderToken(ais, tree, align_kw, Space.None); // align | |
| 1542 | // try renderToken(ais, tree, align_lparen, Space.None); // ( | |
| 1543 | // try renderExpression(allocator, ais, tree, align_expr, Space.None); | |
| 1544 | // try renderToken(ais, tree, align_rparen, Space.Space); // ) | |
| 1545 | // } | |
| 1546 | ||
| 1547 | // if (fn_proto.getSectionExpr()) |section_expr| { | |
| 1548 | // const section_rparen = tree.nextToken(section_expr.lastToken()); | |
| 1549 | // const section_lparen = tree.prevToken(section_expr.firstToken()); | |
| 1550 | // const section_kw = tree.prevToken(section_lparen); | |
| 1551 | ||
| 1552 | // try renderToken(ais, tree, section_kw, Space.None); // section | |
| 1553 | // try renderToken(ais, tree, section_lparen, Space.None); // ( | |
| 1554 | // try renderExpression(allocator, ais, tree, section_expr, Space.None); | |
| 1555 | // try renderToken(ais, tree, section_rparen, Space.Space); // ) | |
| 1556 | // } | |
| 1557 | ||
| 1558 | // if (fn_proto.getCallconvExpr()) |callconv_expr| { | |
| 1559 | // const callconv_rparen = tree.nextToken(callconv_expr.lastToken()); | |
| 1560 | // const callconv_lparen = tree.prevToken(callconv_expr.firstToken()); | |
| 1561 | // const callconv_kw = tree.prevToken(callconv_lparen); | |
| 1562 | ||
| 1563 | // try renderToken(ais, tree, callconv_kw, Space.None); // callconv | |
| 1564 | // try renderToken(ais, tree, callconv_lparen, Space.None); // ( | |
| 1565 | // try renderExpression(allocator, ais, tree, callconv_expr, Space.None); | |
| 1566 | // try renderToken(ais, tree, callconv_rparen, Space.Space); // ) | |
| 1567 | // } else if (fn_proto.getIsExternPrototype() != null) { | |
| 1568 | // try ais.writer().writeAll("callconv(.C) "); | |
| 1569 | // } else if (fn_proto.getIsAsync() != null) { | |
| 1570 | // try ais.writer().writeAll("callconv(.Async) "); | |
| 1571 | // } | |
| 1572 | ||
| 1573 | // switch (fn_proto.return_type) { | |
| 1574 | // .Explicit => |node| { | |
| 1575 | // return renderExpression(allocator, ais, tree, node, space); | |
| 1576 | // }, | |
| 1577 | // .InferErrorSet => |node| { | |
| 1578 | // try renderToken(ais, tree, tree.prevToken(node.firstToken()), Space.None); // ! | |
| 1579 | // return renderExpression(allocator, ais, tree, node, space); | |
| 1580 | // }, | |
| 1581 | // .Invalid => unreachable, | |
| 1582 | // } | |
| 1583 | //}, | |
| 1584 | ||
| 1585 | //.AnyFrameType => { | |
| 1586 | // const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base); | |
| 1587 | ||
| 1588 | // if (anyframe_type.result) |result| { | |
| 1589 | // try renderToken(ais, tree, anyframe_type.anyframe_token, Space.None); // anyframe | |
| 1590 | // try renderToken(ais, tree, result.arrow_token, Space.None); // -> | |
| 1591 | // return renderExpression(allocator, ais, tree, result.return_type, space); | |
| 1592 | // } else { | |
| 1593 | // return renderToken(ais, tree, anyframe_type.anyframe_token, space); // anyframe | |
| 1594 | // } | |
| 1595 | //}, | |
| 1596 | ||
| 1597 | //.DocComment => unreachable, // doc comments are attached to nodes | |
| 1598 | ||
| 1599 | //.Switch => { | |
| 1600 | // const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base); | |
| 1601 | ||
| 1602 | // try renderToken(ais, tree, switch_node.switch_token, Space.Space); // switch | |
| 1603 | // try renderToken(ais, tree, tree.nextToken(switch_node.switch_token), Space.None); // ( | |
| 1604 | ||
| 1605 | // const rparen = tree.nextToken(switch_node.expr.lastToken()); | |
| 1606 | // const lbrace = tree.nextToken(rparen); | |
| 1607 | ||
| 1608 | // if (switch_node.cases_len == 0) { | |
| 1609 | // try renderExpression(allocator, ais, tree, switch_node.expr, Space.None); | |
| 1610 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 1611 | // try renderToken(ais, tree, lbrace, Space.None); // { | |
| 1612 | // return renderToken(ais, tree, switch_node.rbrace, space); // } | |
| 1613 | // } | |
| 1614 | ||
| 1615 | // try renderExpression(allocator, ais, tree, switch_node.expr, Space.None); | |
| 1616 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 1617 | ||
| 1618 | // { | |
| 1619 | // ais.pushIndentNextLine(); | |
| 1620 | // defer ais.popIndent(); | |
| 1621 | // try renderToken(ais, tree, lbrace, Space.Newline); // { | |
| 1622 | ||
| 1623 | // const cases = switch_node.cases(); | |
| 1624 | // for (cases) |node, i| { | |
| 1625 | // try renderExpression(allocator, ais, tree, node, Space.Comma); | |
| 1626 | ||
| 1627 | // if (i + 1 < cases.len) { | |
| 1628 | // try renderExtraNewline(tree, ais, cases[i + 1]); | |
| 1629 | // } | |
| 1630 | // } | |
| 1631 | // } | |
| 1632 | ||
| 1633 | // return renderToken(ais, tree, switch_node.rbrace, space); // } | |
| 1634 | //}, | |
| 1635 | ||
| 1636 | //.SwitchCase => { | |
| 1637 | // const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base); | |
| 1638 | ||
| 1639 | // assert(switch_case.items_len != 0); | |
| 1640 | // const src_has_trailing_comma = blk: { | |
| 1641 | // const last_node = switch_case.items()[switch_case.items_len - 1]; | |
| 1642 | // const maybe_comma = tree.nextToken(last_node.lastToken()); | |
| 1643 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 1644 | // }; | |
| 1645 | ||
| 1646 | // if (switch_case.items_len == 1 or !src_has_trailing_comma) { | |
| 1647 | // const items = switch_case.items(); | |
| 1648 | // for (items) |node, i| { | |
| 1649 | // if (i + 1 < items.len) { | |
| 1650 | // try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1651 | ||
| 1652 | // const comma_token = tree.nextToken(node.lastToken()); | |
| 1653 | // try renderToken(ais, tree, comma_token, Space.Space); // , | |
| 1654 | // try renderExtraNewline(tree, ais, items[i + 1]); | |
| 1655 | // } else { | |
| 1656 | // try renderExpression(allocator, ais, tree, node, Space.Space); | |
| 1657 | // } | |
| 1658 | // } | |
| 1659 | // } else { | |
| 1660 | // const items = switch_case.items(); | |
| 1661 | // for (items) |node, i| { | |
| 1662 | // if (i + 1 < items.len) { | |
| 1663 | // try renderExpression(allocator, ais, tree, node, Space.None); | |
| 1664 | ||
| 1665 | // const comma_token = tree.nextToken(node.lastToken()); | |
| 1666 | // try renderToken(ais, tree, comma_token, Space.Newline); // , | |
| 1667 | // try renderExtraNewline(tree, ais, items[i + 1]); | |
| 1668 | // } else { | |
| 1669 | // try renderExpression(allocator, ais, tree, node, Space.Comma); | |
| 1670 | // } | |
| 1671 | // } | |
| 1672 | // } | |
| 1673 | ||
| 1674 | // try renderToken(ais, tree, switch_case.arrow_token, Space.Space); // => | |
| 1675 | ||
| 1676 | // if (switch_case.payload) |payload| { | |
| 1677 | // try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 1678 | // } | |
| 1679 | ||
| 1680 | // return renderExpression(allocator, ais, tree, switch_case.expr, space); | |
| 1681 | //}, | |
| 1682 | //.SwitchElse => { | |
| 1683 | // const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base); | |
| 1684 | // return renderToken(ais, tree, switch_else.token, space); | |
| 1685 | //}, | |
| 1686 | //.Else => { | |
| 1687 | // const else_node = @fieldParentPtr(ast.Node.Else, "base", base); | |
| 1688 | ||
| 1689 | // const body_is_block = nodeIsBlock(else_node.body); | |
| 1690 | // const same_line = body_is_block or tree.tokensOnSameLine(else_node.else_token, else_node.body.lastToken()); | |
| 1691 | ||
| 1692 | // const after_else_space = if (same_line or else_node.payload != null) Space.Space else Space.Newline; | |
| 1693 | // try renderToken(ais, tree, else_node.else_token, after_else_space); | |
| 1694 | ||
| 1695 | // if (else_node.payload) |payload| { | |
| 1696 | // const payload_space = if (same_line) Space.Space else Space.Newline; | |
| 1697 | // try renderExpression(allocator, ais, tree, payload, payload_space); | |
| 1698 | // } | |
| 1699 | ||
| 1700 | // if (same_line) { | |
| 1701 | // return renderExpression(allocator, ais, tree, else_node.body, space); | |
| 1702 | // } else { | |
| 1703 | // ais.pushIndent(); | |
| 1704 | // defer ais.popIndent(); | |
| 1705 | // return renderExpression(allocator, ais, tree, else_node.body, space); | |
| 1706 | // } | |
| 1707 | //}, | |
| 1708 | ||
| 1709 | //.While => { | |
| 1710 | // const while_node = @fieldParentPtr(ast.Node.While, "base", base); | |
| 1711 | ||
| 1712 | // if (while_node.label) |label| { | |
| 1713 | // try renderToken(ais, tree, label, Space.None); // label | |
| 1714 | // try renderToken(ais, tree, tree.nextToken(label), Space.Space); // : | |
| 1715 | // } | |
| 1716 | ||
| 1717 | // if (while_node.inline_token) |inline_token| { | |
| 1718 | // try renderToken(ais, tree, inline_token, Space.Space); // inline | |
| 1719 | // } | |
| 1720 | ||
| 1721 | // try renderToken(ais, tree, while_node.while_token, Space.Space); // while | |
| 1722 | // try renderToken(ais, tree, tree.nextToken(while_node.while_token), Space.None); // ( | |
| 1723 | // try renderExpression(allocator, ais, tree, while_node.condition, Space.None); | |
| 1724 | ||
| 1725 | // const cond_rparen = tree.nextToken(while_node.condition.lastToken()); | |
| 1726 | ||
| 1727 | // const body_is_block = nodeIsBlock(while_node.body); | |
| 1728 | ||
| 1729 | // var block_start_space: Space = undefined; | |
| 1730 | // var after_body_space: Space = undefined; | |
| 1731 | ||
| 1732 | // if (body_is_block) { | |
| 1733 | // block_start_space = Space.BlockStart; | |
| 1734 | // after_body_space = if (while_node.@"else" == null) space else Space.SpaceOrOutdent; | |
| 1735 | // } else if (tree.tokensOnSameLine(cond_rparen, while_node.body.lastToken())) { | |
| 1736 | // block_start_space = Space.Space; | |
| 1737 | // after_body_space = if (while_node.@"else" == null) space else Space.Space; | |
| 1738 | // } else { | |
| 1739 | // block_start_space = Space.Newline; | |
| 1740 | // after_body_space = if (while_node.@"else" == null) space else Space.Newline; | |
| 1741 | // } | |
| 1742 | ||
| 1743 | // { | |
| 1744 | // const rparen_space = if (while_node.payload != null or while_node.continue_expr != null) Space.Space else block_start_space; | |
| 1745 | // try renderToken(ais, tree, cond_rparen, rparen_space); // ) | |
| 1746 | // } | |
| 1747 | ||
| 1748 | // if (while_node.payload) |payload| { | |
| 1749 | // const payload_space = if (while_node.continue_expr != null) Space.Space else block_start_space; | |
| 1750 | // try renderExpression(allocator, ais, tree, payload, payload_space); | |
| 1751 | // } | |
| 1752 | ||
| 1753 | // if (while_node.continue_expr) |continue_expr| { | |
| 1754 | // const rparen = tree.nextToken(continue_expr.lastToken()); | |
| 1755 | // const lparen = tree.prevToken(continue_expr.firstToken()); | |
| 1756 | // const colon = tree.prevToken(lparen); | |
| 1757 | ||
| 1758 | // try renderToken(ais, tree, colon, Space.Space); // : | |
| 1759 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1760 | ||
| 1761 | // try renderExpression(allocator, ais, tree, continue_expr, Space.None); | |
| 1762 | ||
| 1763 | // try renderToken(ais, tree, rparen, block_start_space); // ) | |
| 1764 | // } | |
| 1765 | ||
| 1766 | // { | |
| 1767 | // if (!body_is_block) ais.pushIndent(); | |
| 1768 | // defer if (!body_is_block) ais.popIndent(); | |
| 1769 | // try renderExpression(allocator, ais, tree, while_node.body, after_body_space); | |
| 1770 | // } | |
| 1771 | ||
| 1772 | // if (while_node.@"else") |@"else"| { | |
| 1773 | // return renderExpression(allocator, ais, tree, &@"else".base, space); | |
| 1774 | // } | |
| 1775 | //}, | |
| 1776 | ||
| 1777 | //.For => { | |
| 1778 | // const for_node = @fieldParentPtr(ast.Node.For, "base", base); | |
| 1779 | ||
| 1780 | // if (for_node.label) |label| { | |
| 1781 | // try renderToken(ais, tree, label, Space.None); // label | |
| 1782 | // try renderToken(ais, tree, tree.nextToken(label), Space.Space); // : | |
| 1783 | // } | |
| 1784 | ||
| 1785 | // if (for_node.inline_token) |inline_token| { | |
| 1786 | // try renderToken(ais, tree, inline_token, Space.Space); // inline | |
| 1787 | // } | |
| 1788 | ||
| 1789 | // try renderToken(ais, tree, for_node.for_token, Space.Space); // for | |
| 1790 | // try renderToken(ais, tree, tree.nextToken(for_node.for_token), Space.None); // ( | |
| 1791 | // try renderExpression(allocator, ais, tree, for_node.array_expr, Space.None); | |
| 1792 | ||
| 1793 | // const rparen = tree.nextToken(for_node.array_expr.lastToken()); | |
| 1794 | ||
| 1795 | // const body_is_block = for_node.body.tag.isBlock(); | |
| 1796 | // const src_one_line_to_body = !body_is_block and tree.tokensOnSameLine(rparen, for_node.body.firstToken()); | |
| 1797 | // const body_on_same_line = body_is_block or src_one_line_to_body; | |
| 1798 | ||
| 1799 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 1800 | ||
| 1801 | // const space_after_payload = if (body_on_same_line) Space.Space else Space.Newline; | |
| 1802 | // try renderExpression(allocator, ais, tree, for_node.payload, space_after_payload); // |x| | |
| 1803 | ||
| 1804 | // const space_after_body = blk: { | |
| 1805 | // if (for_node.@"else") |@"else"| { | |
| 1806 | // const src_one_line_to_else = tree.tokensOnSameLine(rparen, @"else".firstToken()); | |
| 1807 | // if (body_is_block or src_one_line_to_else) { | |
| 1808 | // break :blk Space.Space; | |
| 1809 | // } else { | |
| 1810 | // break :blk Space.Newline; | |
| 1811 | // } | |
| 1812 | // } else { | |
| 1813 | // break :blk space; | |
| 1814 | // } | |
| 1815 | // }; | |
| 1816 | ||
| 1817 | // { | |
| 1818 | // if (!body_on_same_line) ais.pushIndent(); | |
| 1819 | // defer if (!body_on_same_line) ais.popIndent(); | |
| 1820 | // try renderExpression(allocator, ais, tree, for_node.body, space_after_body); // { body } | |
| 1821 | // } | |
| 1822 | ||
| 1823 | // if (for_node.@"else") |@"else"| { | |
| 1824 | // return renderExpression(allocator, ais, tree, &@"else".base, space); // else | |
| 1825 | // } | |
| 1826 | //}, | |
| 1827 | ||
| 1828 | //.If => { | |
| 1829 | // const if_node = @fieldParentPtr(ast.Node.If, "base", base); | |
| 1830 | ||
| 1831 | // const lparen = tree.nextToken(if_node.if_token); | |
| 1832 | // const rparen = tree.nextToken(if_node.condition.lastToken()); | |
| 1833 | ||
| 1834 | // try renderToken(ais, tree, if_node.if_token, Space.Space); // if | |
| 1835 | // try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1836 | ||
| 1837 | // try renderExpression(allocator, ais, tree, if_node.condition, Space.None); // condition | |
| 1838 | ||
| 1839 | // const body_is_if_block = if_node.body.tag == .If; | |
| 1840 | // const body_is_block = nodeIsBlock(if_node.body); | |
| 1841 | ||
| 1842 | // if (body_is_if_block) { | |
| 1843 | // try renderExtraNewline(tree, ais, if_node.body); | |
| 1844 | // } else if (body_is_block) { | |
| 1845 | // const after_rparen_space = if (if_node.payload == null) Space.BlockStart else Space.Space; | |
| 1846 | // try renderToken(ais, tree, rparen, after_rparen_space); // ) | |
| 1847 | ||
| 1848 | // if (if_node.payload) |payload| { | |
| 1849 | // try renderExpression(allocator, ais, tree, payload, Space.BlockStart); // |x| | |
| 1850 | // } | |
| 1851 | ||
| 1852 | // if (if_node.@"else") |@"else"| { | |
| 1853 | // try renderExpression(allocator, ais, tree, if_node.body, Space.SpaceOrOutdent); | |
| 1854 | // return renderExpression(allocator, ais, tree, &@"else".base, space); | |
| 1855 | // } else { | |
| 1856 | // return renderExpression(allocator, ais, tree, if_node.body, space); | |
| 1857 | // } | |
| 1858 | // } | |
| 1859 | ||
| 1860 | // const src_has_newline = !tree.tokensOnSameLine(rparen, if_node.body.lastToken()); | |
| 1861 | ||
| 1862 | // if (src_has_newline) { | |
| 1863 | // const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space; | |
| 1864 | ||
| 1865 | // { | |
| 1866 | // ais.pushIndent(); | |
| 1867 | // defer ais.popIndent(); | |
| 1868 | // try renderToken(ais, tree, rparen, after_rparen_space); // ) | |
| 1869 | // } | |
| 1870 | ||
| 1871 | // if (if_node.payload) |payload| { | |
| 1872 | // try renderExpression(allocator, ais, tree, payload, Space.Newline); | |
| 1873 | // } | |
| 1874 | ||
| 1875 | // if (if_node.@"else") |@"else"| { | |
| 1876 | // const else_is_block = nodeIsBlock(@"else".body); | |
| 1877 | ||
| 1878 | // { | |
| 1879 | // ais.pushIndent(); | |
| 1880 | // defer ais.popIndent(); | |
| 1881 | // try renderExpression(allocator, ais, tree, if_node.body, Space.Newline); | |
| 1882 | // } | |
| 1883 | ||
| 1884 | // if (else_is_block) { | |
| 1885 | // try renderToken(ais, tree, @"else".else_token, Space.Space); // else | |
| 1886 | ||
| 1887 | // if (@"else".payload) |payload| { | |
| 1888 | // try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 1889 | // } | |
| 1890 | ||
| 1891 | // return renderExpression(allocator, ais, tree, @"else".body, space); | |
| 1892 | // } else { | |
| 1893 | // const after_else_space = if (@"else".payload == null) Space.Newline else Space.Space; | |
| 1894 | // try renderToken(ais, tree, @"else".else_token, after_else_space); // else | |
| 1895 | ||
| 1896 | // if (@"else".payload) |payload| { | |
| 1897 | // try renderExpression(allocator, ais, tree, payload, Space.Newline); | |
| 1898 | // } | |
| 1899 | ||
| 1900 | // ais.pushIndent(); | |
| 1901 | // defer ais.popIndent(); | |
| 1902 | // return renderExpression(allocator, ais, tree, @"else".body, space); | |
| 1903 | // } | |
| 1904 | // } else { | |
| 1905 | // ais.pushIndent(); | |
| 1906 | // defer ais.popIndent(); | |
| 1907 | // return renderExpression(allocator, ais, tree, if_node.body, space); | |
| 1908 | // } | |
| 1909 | // } | |
| 1910 | ||
| 1911 | // // Single line if statement | |
| 1912 | ||
| 1913 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 1914 | ||
| 1915 | // if (if_node.payload) |payload| { | |
| 1916 | // try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 1917 | // } | |
| 1918 | ||
| 1919 | // if (if_node.@"else") |@"else"| { | |
| 1920 | // try renderExpression(allocator, ais, tree, if_node.body, Space.Space); | |
| 1921 | // try renderToken(ais, tree, @"else".else_token, Space.Space); | |
| 1922 | ||
| 1923 | // if (@"else".payload) |payload| { | |
| 1924 | // try renderExpression(allocator, ais, tree, payload, Space.Space); | |
| 1925 | // } | |
| 1926 | ||
| 1927 | // return renderExpression(allocator, ais, tree, @"else".body, space); | |
| 1928 | // } else { | |
| 1929 | // return renderExpression(allocator, ais, tree, if_node.body, space); | |
| 1930 | // } | |
| 1931 | //}, | |
| 1932 | ||
| 1933 | //.Asm => { | |
| 1934 | // const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base); | |
| 1935 | ||
| 1936 | // try renderToken(ais, tree, asm_node.asm_token, Space.Space); // asm | |
| 1937 | ||
| 1938 | // if (asm_node.volatile_token) |volatile_token| { | |
| 1939 | // try renderToken(ais, tree, volatile_token, Space.Space); // volatile | |
| 1940 | // try renderToken(ais, tree, tree.nextToken(volatile_token), Space.None); // ( | |
| 1941 | // } else { | |
| 1942 | // try renderToken(ais, tree, tree.nextToken(asm_node.asm_token), Space.None); // ( | |
| 1943 | // } | |
| 1944 | ||
| 1945 | // asmblk: { | |
| 1946 | // ais.pushIndent(); | |
| 1947 | // defer ais.popIndent(); | |
| 1948 | ||
| 1949 | // if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) { | |
| 1950 | // try renderExpression(allocator, ais, tree, asm_node.template, Space.None); | |
| 1951 | // break :asmblk; | |
| 1952 | // } | |
| 1953 | ||
| 1954 | // try renderExpression(allocator, ais, tree, asm_node.template, Space.Newline); | |
| 1955 | ||
| 1956 | // ais.setIndentDelta(asm_indent_delta); | |
| 1957 | // defer ais.setIndentDelta(indent_delta); | |
| 1958 | ||
| 1959 | // const colon1 = tree.nextToken(asm_node.template.lastToken()); | |
| 1960 | ||
| 1961 | // const colon2 = if (asm_node.outputs.len == 0) blk: { | |
| 1962 | // try renderToken(ais, tree, colon1, Space.Newline); // : | |
| 1963 | ||
| 1964 | // break :blk tree.nextToken(colon1); | |
| 1965 | // } else blk: { | |
| 1966 | // try renderToken(ais, tree, colon1, Space.Space); // : | |
| 1967 | ||
| 1968 | // ais.pushIndent(); | |
| 1969 | // defer ais.popIndent(); | |
| 1970 | ||
| 1971 | // for (asm_node.outputs) |*asm_output, i| { | |
| 1972 | // if (i + 1 < asm_node.outputs.len) { | |
| 1973 | // const next_asm_output = asm_node.outputs[i + 1]; | |
| 1974 | // try renderAsmOutput(allocator, ais, tree, asm_output, Space.None); | |
| 1975 | ||
| 1976 | // const comma = tree.prevToken(next_asm_output.firstToken()); | |
| 1977 | // try renderToken(ais, tree, comma, Space.Newline); // , | |
| 1978 | // try renderExtraNewlineToken(tree, ais, next_asm_output.firstToken()); | |
| 1979 | // } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) { | |
| 1980 | // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline); | |
| 1981 | // break :asmblk; | |
| 1982 | // } else { | |
| 1983 | // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline); | |
| 1984 | // const comma_or_colon = tree.nextToken(asm_output.lastToken()); | |
| 1985 | // break :blk switch (tree.token_tags[comma_or_colon]) { | |
| 1986 | // .Comma => tree.nextToken(comma_or_colon), | |
| 1987 | // else => comma_or_colon, | |
| 1988 | // }; | |
| 1989 | // } | |
| 1990 | // } | |
| 1991 | // unreachable; | |
| 1992 | // }; | |
| 1993 | ||
| 1994 | // const colon3 = if (asm_node.inputs.len == 0) blk: { | |
| 1995 | // try renderToken(ais, tree, colon2, Space.Newline); // : | |
| 1996 | // break :blk tree.nextToken(colon2); | |
| 1997 | // } else blk: { | |
| 1998 | // try renderToken(ais, tree, colon2, Space.Space); // : | |
| 1999 | // ais.pushIndent(); | |
| 2000 | // defer ais.popIndent(); | |
| 2001 | // for (asm_node.inputs) |*asm_input, i| { | |
| 2002 | // if (i + 1 < asm_node.inputs.len) { | |
| 2003 | // const next_asm_input = &asm_node.inputs[i + 1]; | |
| 2004 | // try renderAsmInput(allocator, ais, tree, asm_input, Space.None); | |
| 2005 | ||
| 2006 | // const comma = tree.prevToken(next_asm_input.firstToken()); | |
| 2007 | // try renderToken(ais, tree, comma, Space.Newline); // , | |
| 2008 | // try renderExtraNewlineToken(tree, ais, next_asm_input.firstToken()); | |
| 2009 | // } else if (asm_node.clobbers.len == 0) { | |
| 2010 | // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline); | |
| 2011 | // break :asmblk; | |
| 2012 | // } else { | |
| 2013 | // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline); | |
| 2014 | // const comma_or_colon = tree.nextToken(asm_input.lastToken()); | |
| 2015 | // break :blk switch (tree.token_tags[comma_or_colon]) { | |
| 2016 | // .Comma => tree.nextToken(comma_or_colon), | |
| 2017 | // else => comma_or_colon, | |
| 2018 | // }; | |
| 2019 | // } | |
| 2020 | // } | |
| 2021 | // unreachable; | |
| 2022 | // }; | |
| 2023 | ||
| 2024 | // try renderToken(ais, tree, colon3, Space.Space); // : | |
| 2025 | // ais.pushIndent(); | |
| 2026 | // defer ais.popIndent(); | |
| 2027 | // for (asm_node.clobbers) |clobber_node, i| { | |
| 2028 | // if (i + 1 >= asm_node.clobbers.len) { | |
| 2029 | // try renderExpression(allocator, ais, tree, clobber_node, Space.Newline); | |
| 2030 | // break :asmblk; | |
| 2031 | // } else { | |
| 2032 | // try renderExpression(allocator, ais, tree, clobber_node, Space.None); | |
| 2033 | // const comma = tree.nextToken(clobber_node.lastToken()); | |
| 2034 | // try renderToken(ais, tree, comma, Space.Space); // , | |
| 2035 | // } | |
| 2036 | // } | |
| 2037 | // } | |
| 2038 | ||
| 2039 | // return renderToken(ais, tree, asm_node.rparen, space); | |
| 2040 | //}, | |
| 2041 | ||
| 2042 | //.EnumLiteral => { | |
| 2043 | // const enum_literal = @fieldParentPtr(ast.Node.EnumLiteral, "base", base); | |
| 2044 | ||
| 2045 | // try renderToken(ais, tree, enum_literal.dot, Space.None); // . | |
| 2046 | // return renderToken(ais, tree, enum_literal.name, space); // name | |
| 2047 | //}, | |
| 2048 | ||
| 2049 | //.ContainerField, | |
| 2050 | //.Root, | |
| 2051 | //.VarDecl, | |
| 2052 | //.Use, | |
| 2053 | //.TestDecl, | |
| 2054 | //=> unreachable, | |
| 2055 | else => @panic("TODO implement more renderExpression"), | |
| 2151 | 2056 | } |
| 2152 | 2057 | } |
| 2153 | 2058 | |
| 2154 | 2059 | fn renderArrayType( |
| 2155 | 2060 | allocator: *mem.Allocator, |
| 2156 | ais: anytype, | |
| 2157 | tree: *ast.Tree, | |
| 2061 | ais: *Ais, | |
| 2062 | tree: ast.Tree, | |
| 2158 | 2063 | lbracket: ast.TokenIndex, |
| 2159 | rhs: *ast.Node, | |
| 2160 | len_expr: *ast.Node, | |
| 2161 | opt_sentinel: ?*ast.Node, | |
| 2064 | rhs: ast.Node.Index, | |
| 2065 | len_expr: ast.Node.Index, | |
| 2066 | opt_sentinel: ?ast.Node.Index, | |
| 2162 | 2067 | space: Space, |
| 2163 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2068 | ) Error!void { | |
| 2164 | 2069 | const rbracket = tree.nextToken(if (opt_sentinel) |sentinel| |
| 2165 | 2070 | sentinel.lastToken() |
| 2166 | 2071 | else |
| 2167 | 2072 | len_expr.lastToken()); |
| 2168 | 2073 | |
| 2169 | const starts_with_comment = tree.token_ids[lbracket + 1] == .LineComment; | |
| 2170 | const ends_with_comment = tree.token_ids[rbracket - 1] == .LineComment; | |
| 2074 | const starts_with_comment = tree.token_tags[lbracket + 1] == .LineComment; | |
| 2075 | const ends_with_comment = tree.token_tags[rbracket - 1] == .LineComment; | |
| 2171 | 2076 | const new_space = if (ends_with_comment) Space.Newline else Space.None; |
| 2172 | 2077 | { |
| 2173 | 2078 | const do_indent = (starts_with_comment or ends_with_comment); |
| 2174 | 2079 | if (do_indent) ais.pushIndent(); |
| 2175 | 2080 | defer if (do_indent) ais.popIndent(); |
| 2176 | 2081 | |
| 2177 | try renderToken(tree, ais, lbracket, Space.None); // [ | |
| 2082 | try renderToken(ais, tree, lbracket, Space.None); // [ | |
| 2178 | 2083 | try renderExpression(allocator, ais, tree, len_expr, new_space); |
| 2179 | 2084 | |
| 2180 | 2085 | if (starts_with_comment) { |
| ... | ... | @@ -2182,25 +2087,25 @@ fn renderArrayType( |
| 2182 | 2087 | } |
| 2183 | 2088 | if (opt_sentinel) |sentinel| { |
| 2184 | 2089 | const colon_token = tree.prevToken(sentinel.firstToken()); |
| 2185 | try renderToken(tree, ais, colon_token, Space.None); // : | |
| 2090 | try renderToken(ais, tree, colon_token, Space.None); // : | |
| 2186 | 2091 | try renderExpression(allocator, ais, tree, sentinel, Space.None); |
| 2187 | 2092 | } |
| 2188 | 2093 | if (starts_with_comment) { |
| 2189 | 2094 | try ais.maybeInsertNewline(); |
| 2190 | 2095 | } |
| 2191 | 2096 | } |
| 2192 | try renderToken(tree, ais, rbracket, Space.None); // ] | |
| 2097 | try renderToken(ais, tree, rbracket, Space.None); // ] | |
| 2193 | 2098 | |
| 2194 | 2099 | return renderExpression(allocator, ais, tree, rhs, space); |
| 2195 | 2100 | } |
| 2196 | 2101 | |
| 2197 | 2102 | fn renderAsmOutput( |
| 2198 | 2103 | allocator: *mem.Allocator, |
| 2199 | ais: anytype, | |
| 2200 | tree: *ast.Tree, | |
| 2104 | ais: *Ais, | |
| 2105 | tree: ast.Tree, | |
| 2201 | 2106 | asm_output: *const ast.Node.Asm.Output, |
| 2202 | 2107 | space: Space, |
| 2203 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2108 | ) Error!void { | |
| 2204 | 2109 | try ais.writer().writeAll("["); |
| 2205 | 2110 | try renderExpression(allocator, ais, tree, asm_output.symbolic_name, Space.None); |
| 2206 | 2111 | try ais.writer().writeAll("] "); |
| ... | ... | @@ -2217,37 +2122,37 @@ fn renderAsmOutput( |
| 2217 | 2122 | }, |
| 2218 | 2123 | } |
| 2219 | 2124 | |
| 2220 | return renderToken(tree, ais, asm_output.lastToken(), space); // ) | |
| 2125 | return renderToken(ais, tree, asm_output.lastToken(), space); // ) | |
| 2221 | 2126 | } |
| 2222 | 2127 | |
| 2223 | 2128 | fn renderAsmInput( |
| 2224 | 2129 | allocator: *mem.Allocator, |
| 2225 | ais: anytype, | |
| 2226 | tree: *ast.Tree, | |
| 2130 | ais: *Ais, | |
| 2131 | tree: ast.Tree, | |
| 2227 | 2132 | asm_input: *const ast.Node.Asm.Input, |
| 2228 | 2133 | space: Space, |
| 2229 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2134 | ) Error!void { | |
| 2230 | 2135 | try ais.writer().writeAll("["); |
| 2231 | 2136 | try renderExpression(allocator, ais, tree, asm_input.symbolic_name, Space.None); |
| 2232 | 2137 | try ais.writer().writeAll("] "); |
| 2233 | 2138 | try renderExpression(allocator, ais, tree, asm_input.constraint, Space.None); |
| 2234 | 2139 | try ais.writer().writeAll(" ("); |
| 2235 | 2140 | try renderExpression(allocator, ais, tree, asm_input.expr, Space.None); |
| 2236 | return renderToken(tree, ais, asm_input.lastToken(), space); // ) | |
| 2141 | return renderToken(ais, tree, asm_input.lastToken(), space); // ) | |
| 2237 | 2142 | } |
| 2238 | 2143 | |
| 2239 | 2144 | fn renderVarDecl( |
| 2240 | 2145 | allocator: *mem.Allocator, |
| 2241 | ais: anytype, | |
| 2242 | tree: *ast.Tree, | |
| 2243 | var_decl: *ast.Node.VarDecl, | |
| 2244 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2146 | ais: *Ais, | |
| 2147 | tree: ast.Tree, | |
| 2148 | var_decl: ast.Node.Index.VarDecl, | |
| 2149 | ) Error!void { | |
| 2245 | 2150 | if (var_decl.getVisibToken()) |visib_token| { |
| 2246 | try renderToken(tree, ais, visib_token, Space.Space); // pub | |
| 2151 | try renderToken(ais, tree, visib_token, Space.Space); // pub | |
| 2247 | 2152 | } |
| 2248 | 2153 | |
| 2249 | 2154 | if (var_decl.getExternExportToken()) |extern_export_token| { |
| 2250 | try renderToken(tree, ais, extern_export_token, Space.Space); // extern | |
| 2155 | try renderToken(ais, tree, extern_export_token, Space.Space); // extern | |
| 2251 | 2156 | |
| 2252 | 2157 | if (var_decl.getLibName()) |lib_name| { |
| 2253 | 2158 | try renderExpression(allocator, ais, tree, lib_name, Space.Space); // "lib" |
| ... | ... | @@ -2255,13 +2160,13 @@ fn renderVarDecl( |
| 2255 | 2160 | } |
| 2256 | 2161 | |
| 2257 | 2162 | if (var_decl.getComptimeToken()) |comptime_token| { |
| 2258 | try renderToken(tree, ais, comptime_token, Space.Space); // comptime | |
| 2163 | try renderToken(ais, tree, comptime_token, Space.Space); // comptime | |
| 2259 | 2164 | } |
| 2260 | 2165 | |
| 2261 | 2166 | if (var_decl.getThreadLocalToken()) |thread_local_token| { |
| 2262 | try renderToken(tree, ais, thread_local_token, Space.Space); // threadlocal | |
| 2167 | try renderToken(ais, tree, thread_local_token, Space.Space); // threadlocal | |
| 2263 | 2168 | } |
| 2264 | try renderToken(tree, ais, var_decl.mut_token, Space.Space); // var | |
| 2169 | try renderToken(ais, tree, var_decl.mut_token, Space.Space); // var | |
| 2265 | 2170 | |
| 2266 | 2171 | const name_space = if (var_decl.getTypeNode() == null and |
| 2267 | 2172 | (var_decl.getAlignNode() != null or |
| ... | ... | @@ -2270,10 +2175,10 @@ fn renderVarDecl( |
| 2270 | 2175 | Space.Space |
| 2271 | 2176 | else |
| 2272 | 2177 | Space.None; |
| 2273 | try renderToken(tree, ais, var_decl.name_token, name_space); | |
| 2178 | try renderToken(ais, tree, var_decl.name_token, name_space); | |
| 2274 | 2179 | |
| 2275 | 2180 | if (var_decl.getTypeNode()) |type_node| { |
| 2276 | try renderToken(tree, ais, tree.nextToken(var_decl.name_token), Space.Space); | |
| 2181 | try renderToken(ais, tree, tree.nextToken(var_decl.name_token), Space.Space); | |
| 2277 | 2182 | const s = if (var_decl.getAlignNode() != null or |
| 2278 | 2183 | var_decl.getSectionNode() != null or |
| 2279 | 2184 | var_decl.getInitNode() != null) Space.Space else Space.None; |
| ... | ... | @@ -2284,22 +2189,22 @@ fn renderVarDecl( |
| 2284 | 2189 | const lparen = tree.prevToken(align_node.firstToken()); |
| 2285 | 2190 | const align_kw = tree.prevToken(lparen); |
| 2286 | 2191 | const rparen = tree.nextToken(align_node.lastToken()); |
| 2287 | try renderToken(tree, ais, align_kw, Space.None); // align | |
| 2288 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 2192 | try renderToken(ais, tree, align_kw, Space.None); // align | |
| 2193 | try renderToken(ais, tree, lparen, Space.None); // ( | |
| 2289 | 2194 | try renderExpression(allocator, ais, tree, align_node, Space.None); |
| 2290 | 2195 | const s = if (var_decl.getSectionNode() != null or var_decl.getInitNode() != null) Space.Space else Space.None; |
| 2291 | try renderToken(tree, ais, rparen, s); // ) | |
| 2196 | try renderToken(ais, tree, rparen, s); // ) | |
| 2292 | 2197 | } |
| 2293 | 2198 | |
| 2294 | 2199 | if (var_decl.getSectionNode()) |section_node| { |
| 2295 | 2200 | const lparen = tree.prevToken(section_node.firstToken()); |
| 2296 | 2201 | const section_kw = tree.prevToken(lparen); |
| 2297 | 2202 | const rparen = tree.nextToken(section_node.lastToken()); |
| 2298 | try renderToken(tree, ais, section_kw, Space.None); // linksection | |
| 2299 | try renderToken(tree, ais, lparen, Space.None); // ( | |
| 2203 | try renderToken(ais, tree, section_kw, Space.None); // linksection | |
| 2204 | try renderToken(ais, tree, lparen, Space.None); // ( | |
| 2300 | 2205 | try renderExpression(allocator, ais, tree, section_node, Space.None); |
| 2301 | 2206 | const s = if (var_decl.getInitNode() != null) Space.Space else Space.None; |
| 2302 | try renderToken(tree, ais, rparen, s); // ) | |
| 2207 | try renderToken(ais, tree, rparen, s); // ) | |
| 2303 | 2208 | } |
| 2304 | 2209 | |
| 2305 | 2210 | if (var_decl.getInitNode()) |init_node| { |
| ... | ... | @@ -2312,268 +2217,150 @@ fn renderVarDecl( |
| 2312 | 2217 | { |
| 2313 | 2218 | ais.pushIndent(); |
| 2314 | 2219 | defer ais.popIndent(); |
| 2315 | try renderToken(tree, ais, eq_token, eq_space); // = | |
| 2220 | try renderToken(ais, tree, eq_token, eq_space); // = | |
| 2316 | 2221 | } |
| 2317 | 2222 | ais.pushIndentOneShot(); |
| 2318 | 2223 | try renderExpression(allocator, ais, tree, init_node, Space.None); |
| 2319 | 2224 | } |
| 2320 | 2225 | |
| 2321 | try renderToken(tree, ais, var_decl.semicolon_token, Space.Newline); | |
| 2226 | try renderToken(ais, tree, var_decl.semicolon_token, Space.Newline); | |
| 2322 | 2227 | } |
| 2323 | 2228 | |
| 2324 | 2229 | fn renderParamDecl( |
| 2325 | 2230 | allocator: *mem.Allocator, |
| 2326 | ais: anytype, | |
| 2327 | tree: *ast.Tree, | |
| 2231 | ais: *Ais, | |
| 2232 | tree: ast.Tree, | |
| 2328 | 2233 | param_decl: ast.Node.FnProto.ParamDecl, |
| 2329 | 2234 | space: Space, |
| 2330 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2235 | ) Error!void { | |
| 2331 | 2236 | try renderDocComments(tree, ais, param_decl, param_decl.doc_comments); |
| 2332 | 2237 | |
| 2333 | 2238 | if (param_decl.comptime_token) |comptime_token| { |
| 2334 | try renderToken(tree, ais, comptime_token, Space.Space); | |
| 2239 | try renderToken(ais, tree, comptime_token, Space.Space); | |
| 2335 | 2240 | } |
| 2336 | 2241 | if (param_decl.noalias_token) |noalias_token| { |
| 2337 | try renderToken(tree, ais, noalias_token, Space.Space); | |
| 2242 | try renderToken(ais, tree, noalias_token, Space.Space); | |
| 2338 | 2243 | } |
| 2339 | 2244 | if (param_decl.name_token) |name_token| { |
| 2340 | try renderToken(tree, ais, name_token, Space.None); | |
| 2341 | try renderToken(tree, ais, tree.nextToken(name_token), Space.Space); // : | |
| 2245 | try renderToken(ais, tree, name_token, Space.None); | |
| 2246 | try renderToken(ais, tree, tree.nextToken(name_token), Space.Space); // : | |
| 2342 | 2247 | } |
| 2343 | 2248 | switch (param_decl.param_type) { |
| 2344 | 2249 | .any_type, .type_expr => |node| try renderExpression(allocator, ais, tree, node, space), |
| 2345 | 2250 | } |
| 2346 | 2251 | } |
| 2347 | 2252 | |
| 2348 | fn renderStatement( | |
| 2349 | allocator: *mem.Allocator, | |
| 2350 | ais: anytype, | |
| 2351 | tree: *ast.Tree, | |
| 2352 | base: *ast.Node, | |
| 2353 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2354 | switch (base.tag) { | |
| 2355 | .VarDecl => { | |
| 2356 | const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base); | |
| 2357 | try renderVarDecl(allocator, ais, tree, var_decl); | |
| 2358 | }, | |
| 2359 | else => { | |
| 2360 | if (base.requireSemiColon()) { | |
| 2361 | try renderExpression(allocator, ais, tree, base, Space.None); | |
| 2362 | ||
| 2363 | const semicolon_index = tree.nextToken(base.lastToken()); | |
| 2364 | assert(tree.token_ids[semicolon_index] == .Semicolon); | |
| 2365 | try renderToken(tree, ais, semicolon_index, Space.Newline); | |
| 2366 | } else { | |
| 2367 | try renderExpression(allocator, ais, tree, base, Space.Newline); | |
| 2368 | } | |
| 2369 | }, | |
| 2370 | } | |
| 2253 | fn renderStatement(ais: *Ais, tree: ast.Tree, base: ast.Node.Index) Error!void { | |
| 2254 | @panic("TODO render statement"); | |
| 2255 | //switch (base.tag) { | |
| 2256 | // .VarDecl => { | |
| 2257 | // const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base); | |
| 2258 | // try renderVarDecl(allocator, ais, tree, var_decl); | |
| 2259 | // }, | |
| 2260 | // else => { | |
| 2261 | // if (base.requireSemiColon()) { | |
| 2262 | // try renderExpression(allocator, ais, tree, base, Space.None); | |
| 2263 | ||
| 2264 | // const semicolon_index = tree.nextToken(base.lastToken()); | |
| 2265 | // assert(tree.token_tags[semicolon_index] == .Semicolon); | |
| 2266 | // try renderToken(ais, tree, semicolon_index, Space.Newline); | |
| 2267 | // } else { | |
| 2268 | // try renderExpression(allocator, ais, tree, base, Space.Newline); | |
| 2269 | // } | |
| 2270 | // }, | |
| 2271 | //} | |
| 2371 | 2272 | } |
| 2372 | 2273 | |
| 2373 | 2274 | const Space = enum { |
| 2374 | 2275 | None, |
| 2375 | 2276 | Newline, |
| 2277 | /// `renderToken` will additionally consume the next token if it is a comma. | |
| 2376 | 2278 | Comma, |
| 2377 | 2279 | Space, |
| 2378 | 2280 | SpaceOrOutdent, |
| 2379 | 2281 | NoNewline, |
| 2282 | /// Skips writing the possible line comment after the token. | |
| 2380 | 2283 | NoComment, |
| 2381 | 2284 | BlockStart, |
| 2382 | 2285 | }; |
| 2383 | 2286 | |
| 2384 | fn renderTokenOffset( | |
| 2385 | tree: *ast.Tree, | |
| 2386 | ais: anytype, | |
| 2387 | token_index: ast.TokenIndex, | |
| 2388 | space: Space, | |
| 2389 | token_skip_bytes: usize, | |
| 2390 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2287 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { | |
| 2391 | 2288 | if (space == Space.BlockStart) { |
| 2392 | // If placing the lbrace on the current line would cause an uggly gap then put the lbrace on the next line | |
| 2289 | // If placing the lbrace on the current line would cause an ugly gap then put the lbrace on the next line. | |
| 2393 | 2290 | const new_space = if (ais.isLineOverIndented()) Space.Newline else Space.Space; |
| 2394 | return renderToken(tree, ais, token_index, new_space); | |
| 2291 | return renderToken(ais, tree, token_index, new_space); | |
| 2395 | 2292 | } |
| 2396 | 2293 | |
| 2397 | var token_loc = tree.token_locs[token_index]; | |
| 2398 | try ais.writer().writeAll(mem.trimRight(u8, tree.tokenSliceLoc(token_loc)[token_skip_bytes..], " ")); | |
| 2294 | const token_tags = tree.tokens.items(.tag); | |
| 2295 | const token_starts = tree.tokens.items(.start); | |
| 2399 | 2296 | |
| 2400 | if (space == Space.NoComment) | |
| 2401 | return; | |
| 2297 | const token_start = token_starts[token_index]; | |
| 2298 | const token_tag = token_tags[token_index]; | |
| 2299 | const lexeme = token_tag.lexeme() orelse lexeme: { | |
| 2300 | var tokenizer: std.zig.Tokenizer = .{ | |
| 2301 | .buffer = tree.source, | |
| 2302 | .index = token_start, | |
| 2303 | .pending_invalid_token = null, | |
| 2304 | }; | |
| 2305 | const token = tokenizer.next(); | |
| 2306 | assert(token.tag == token_tag); | |
| 2307 | break :lexeme tree.source[token.loc.start..token.loc.end]; | |
| 2308 | }; | |
| 2309 | try ais.writer().writeAll(lexeme); | |
| 2402 | 2310 | |
| 2403 | var next_token_id = tree.token_ids[token_index + 1]; | |
| 2404 | var next_token_loc = tree.token_locs[token_index + 1]; | |
| 2311 | switch (space) { | |
| 2312 | .NoComment => {}, | |
| 2313 | .NoNewline => {}, | |
| 2314 | .None => {}, | |
| 2315 | .Comma => { | |
| 2316 | const count = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ", "); | |
| 2317 | if (count == 0 and token_tags[token_index + 1] == .Comma) { | |
| 2318 | return renderToken(ais, tree, token_index + 1, Space.Newline); | |
| 2319 | } | |
| 2320 | try ais.writer().writeAll(","); | |
| 2405 | 2321 | |
| 2406 | if (space == Space.Comma) switch (next_token_id) { | |
| 2407 | .Comma => return renderToken(tree, ais, token_index + 1, Space.Newline), | |
| 2408 | .LineComment => { | |
| 2409 | try ais.writer().writeAll(", "); | |
| 2410 | return renderToken(tree, ais, token_index + 1, Space.Newline); | |
| 2411 | }, | |
| 2412 | else => { | |
| 2413 | if (token_index + 2 < tree.token_ids.len and | |
| 2414 | tree.token_ids[token_index + 2] == .MultilineStringLiteralLine) | |
| 2415 | { | |
| 2416 | try ais.writer().writeAll(","); | |
| 2417 | return; | |
| 2418 | } else { | |
| 2419 | try ais.writer().writeAll(","); | |
| 2322 | if (token_tags[token_index + 2] != .MultilineStringLiteralLine) { | |
| 2420 | 2323 | try ais.insertNewline(); |
| 2421 | return; | |
| 2422 | 2324 | } |
| 2423 | 2325 | }, |
| 2424 | }; | |
| 2425 | ||
| 2426 | // Skip over same line doc comments | |
| 2427 | var offset: usize = 1; | |
| 2428 | if (next_token_id == .DocComment) { | |
| 2429 | const loc = tree.tokenLocationLoc(token_loc.end, next_token_loc); | |
| 2430 | if (loc.line == 0) { | |
| 2431 | offset += 1; | |
| 2432 | next_token_id = tree.token_ids[token_index + offset]; | |
| 2433 | next_token_loc = tree.token_locs[token_index + offset]; | |
| 2434 | } | |
| 2435 | } | |
| 2436 | ||
| 2437 | if (next_token_id != .LineComment) { | |
| 2438 | switch (space) { | |
| 2439 | Space.None, Space.NoNewline => return, | |
| 2440 | Space.Newline => { | |
| 2441 | if (next_token_id == .MultilineStringLiteralLine) { | |
| 2442 | return; | |
| 2443 | } else { | |
| 2444 | try ais.insertNewline(); | |
| 2445 | return; | |
| 2446 | } | |
| 2447 | }, | |
| 2448 | Space.Space, Space.SpaceOrOutdent => { | |
| 2449 | if (next_token_id == .MultilineStringLiteralLine) | |
| 2450 | return; | |
| 2451 | try ais.writer().writeByte(' '); | |
| 2452 | return; | |
| 2453 | }, | |
| 2454 | Space.NoComment, Space.Comma, Space.BlockStart => unreachable, | |
| 2455 | } | |
| 2456 | } | |
| 2457 | ||
| 2458 | while (true) { | |
| 2459 | const comment_is_empty = mem.trimRight(u8, tree.tokenSliceLoc(next_token_loc), " ").len == 2; | |
| 2460 | if (comment_is_empty) { | |
| 2461 | switch (space) { | |
| 2462 | Space.Newline => { | |
| 2463 | offset += 1; | |
| 2464 | token_loc = next_token_loc; | |
| 2465 | next_token_id = tree.token_ids[token_index + offset]; | |
| 2466 | next_token_loc = tree.token_locs[token_index + offset]; | |
| 2467 | if (next_token_id != .LineComment) { | |
| 2468 | try ais.insertNewline(); | |
| 2469 | return; | |
| 2470 | } | |
| 2471 | }, | |
| 2472 | else => break, | |
| 2473 | } | |
| 2474 | } else { | |
| 2475 | break; | |
| 2476 | } | |
| 2477 | } | |
| 2478 | ||
| 2479 | var loc = tree.tokenLocationLoc(token_loc.end, next_token_loc); | |
| 2480 | if (loc.line == 0) { | |
| 2481 | if (tree.token_ids[token_index] != .MultilineStringLiteralLine) { | |
| 2326 | .SpaceOrOutdent => @panic("what does this even do"), | |
| 2327 | .Space => { | |
| 2328 | _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ""); | |
| 2482 | 2329 | try ais.writer().writeByte(' '); |
| 2483 | } | |
| 2484 | try ais.writer().writeAll(mem.trimRight(u8, tree.tokenSliceLoc(next_token_loc), " ")); | |
| 2485 | offset = 2; | |
| 2486 | token_loc = next_token_loc; | |
| 2487 | next_token_loc = tree.token_locs[token_index + offset]; | |
| 2488 | next_token_id = tree.token_ids[token_index + offset]; | |
| 2489 | if (next_token_id != .LineComment) { | |
| 2490 | switch (space) { | |
| 2491 | .None, .Space, .SpaceOrOutdent => { | |
| 2492 | try ais.insertNewline(); | |
| 2493 | }, | |
| 2494 | .Newline => { | |
| 2495 | if (next_token_id == .MultilineStringLiteralLine) { | |
| 2496 | return; | |
| 2497 | } else { | |
| 2498 | try ais.insertNewline(); | |
| 2499 | return; | |
| 2500 | } | |
| 2501 | }, | |
| 2502 | .NoNewline => {}, | |
| 2503 | .NoComment, .Comma, .BlockStart => unreachable, | |
| 2504 | } | |
| 2505 | return; | |
| 2506 | } | |
| 2507 | loc = tree.tokenLocationLoc(token_loc.end, next_token_loc); | |
| 2508 | } | |
| 2509 | ||
| 2510 | while (true) { | |
| 2511 | // translate-c doesn't generate correct newlines | |
| 2512 | // in generated code (loc.line == 0) so treat that case | |
| 2513 | // as though there was meant to be a newline between the tokens | |
| 2514 | var newline_count = if (loc.line <= 1) @as(u8, 1) else @as(u8, 2); | |
| 2515 | while (newline_count > 0) : (newline_count -= 1) try ais.insertNewline(); | |
| 2516 | try ais.writer().writeAll(mem.trimRight(u8, tree.tokenSliceLoc(next_token_loc), " ")); | |
| 2517 | ||
| 2518 | offset += 1; | |
| 2519 | token_loc = next_token_loc; | |
| 2520 | next_token_loc = tree.token_locs[token_index + offset]; | |
| 2521 | next_token_id = tree.token_ids[token_index + offset]; | |
| 2522 | if (next_token_id != .LineComment) { | |
| 2523 | switch (space) { | |
| 2524 | .Newline => { | |
| 2525 | if (next_token_id == .MultilineStringLiteralLine) { | |
| 2526 | return; | |
| 2527 | } else { | |
| 2528 | try ais.insertNewline(); | |
| 2529 | return; | |
| 2530 | } | |
| 2531 | }, | |
| 2532 | .None, .Space, .SpaceOrOutdent => { | |
| 2533 | try ais.insertNewline(); | |
| 2534 | }, | |
| 2535 | .NoNewline => {}, | |
| 2536 | .NoComment, .Comma, .BlockStart => unreachable, | |
| 2330 | }, | |
| 2331 | .Newline => { | |
| 2332 | if (token_tags[token_index + 1] != .MultilineStringLiteralLine) { | |
| 2333 | try ais.insertNewline(); | |
| 2537 | 2334 | } |
| 2538 | return; | |
| 2539 | } | |
| 2540 | loc = tree.tokenLocationLoc(token_loc.end, next_token_loc); | |
| 2335 | }, | |
| 2336 | .BlockStart => unreachable, | |
| 2541 | 2337 | } |
| 2542 | 2338 | } |
| 2543 | 2339 | |
| 2544 | fn renderToken( | |
| 2545 | tree: *ast.Tree, | |
| 2546 | ais: anytype, | |
| 2547 | token_index: ast.TokenIndex, | |
| 2548 | space: Space, | |
| 2549 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2550 | return renderTokenOffset(tree, ais, token_index, space, 0); | |
| 2551 | } | |
| 2552 | ||
| 2553 | 2340 | fn renderDocComments( |
| 2554 | tree: *ast.Tree, | |
| 2555 | ais: anytype, | |
| 2341 | tree: ast.Tree, | |
| 2342 | ais: *Ais, | |
| 2556 | 2343 | node: anytype, |
| 2557 | doc_comments: ?*ast.Node.DocComment, | |
| 2558 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2344 | doc_comments: ?ast.Node.Index.DocComment, | |
| 2345 | ) Error!void { | |
| 2559 | 2346 | const comment = doc_comments orelse return; |
| 2560 | 2347 | return renderDocCommentsToken(tree, ais, comment, node.firstToken()); |
| 2561 | 2348 | } |
| 2562 | 2349 | |
| 2563 | 2350 | fn renderDocCommentsToken( |
| 2564 | tree: *ast.Tree, | |
| 2565 | ais: anytype, | |
| 2566 | comment: *ast.Node.DocComment, | |
| 2351 | tree: ast.Tree, | |
| 2352 | ais: *Ais, | |
| 2353 | comment: ast.Node.Index.DocComment, | |
| 2567 | 2354 | first_token: ast.TokenIndex, |
| 2568 | ) (@TypeOf(ais.*).Error || Error)!void { | |
| 2355 | ) Error!void { | |
| 2569 | 2356 | var tok_i = comment.first_line; |
| 2570 | 2357 | while (true) : (tok_i += 1) { |
| 2571 | switch (tree.token_ids[tok_i]) { | |
| 2358 | switch (tree.token_tags[tok_i]) { | |
| 2572 | 2359 | .DocComment, .ContainerDocComment => { |
| 2573 | 2360 | if (comment.first_line < first_token) { |
| 2574 | try renderToken(tree, ais, tok_i, Space.Newline); | |
| 2361 | try renderToken(ais, tree, tok_i, Space.Newline); | |
| 2575 | 2362 | } else { |
| 2576 | try renderToken(tree, ais, tok_i, Space.NoComment); | |
| 2363 | try renderToken(ais, tree, tok_i, Space.NoComment); | |
| 2577 | 2364 | try ais.insertNewline(); |
| 2578 | 2365 | } |
| 2579 | 2366 | }, |
| ... | ... | @@ -2596,7 +2383,7 @@ fn nodeIsBlock(base: *const ast.Node) bool { |
| 2596 | 2383 | }; |
| 2597 | 2384 | } |
| 2598 | 2385 | |
| 2599 | fn nodeCausesSliceOpSpace(base: *ast.Node) bool { | |
| 2386 | fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { | |
| 2600 | 2387 | return switch (base.tag) { |
| 2601 | 2388 | .Catch, |
| 2602 | 2389 | .Add, |
| ... | ... | @@ -2646,7 +2433,7 @@ fn nodeCausesSliceOpSpace(base: *ast.Node) bool { |
| 2646 | 2433 | }; |
| 2647 | 2434 | } |
| 2648 | 2435 | |
| 2649 | fn copyFixingWhitespace(ais: anytype, slice: []const u8) @TypeOf(ais.*).Error!void { | |
| 2436 | fn copyFixingWhitespace(ais: *Ais, slice: []const u8) @TypeOf(ais.*).Error!void { | |
| 2650 | 2437 | for (slice) |byte| switch (byte) { |
| 2651 | 2438 | '\t' => try ais.writer().writeAll(" "), |
| 2652 | 2439 | '\r' => {}, |
| ... | ... | @@ -2656,12 +2443,12 @@ fn copyFixingWhitespace(ais: anytype, slice: []const u8) @TypeOf(ais.*).Error!vo |
| 2656 | 2443 | |
| 2657 | 2444 | // Returns the number of nodes in `expr` that are on the same line as `rtoken`, |
| 2658 | 2445 | // or null if they all are on the same line. |
| 2659 | fn rowSize(tree: *ast.Tree, exprs: []*ast.Node, rtoken: ast.TokenIndex) ?usize { | |
| 2446 | fn rowSize(tree: ast.Tree, exprs: []ast.Node.Index, rtoken: ast.TokenIndex) ?usize { | |
| 2660 | 2447 | const first_token = exprs[0].firstToken(); |
| 2661 | 2448 | const first_loc = tree.tokenLocation(tree.token_locs[first_token].start, rtoken); |
| 2662 | 2449 | if (first_loc.line == 0) { |
| 2663 | 2450 | const maybe_comma = tree.prevToken(rtoken); |
| 2664 | if (tree.token_ids[maybe_comma] == .Comma) | |
| 2451 | if (tree.token_tags[maybe_comma] == .Comma) | |
| 2665 | 2452 | return 1; |
| 2666 | 2453 | return null; // no newlines |
| 2667 | 2454 | } |
lib/std/zig/tokenizer.zig+18-13| ... | ... | @@ -195,22 +195,23 @@ pub const Token = struct { |
| 195 | 195 | Keyword_volatile, |
| 196 | 196 | Keyword_while, |
| 197 | 197 | |
| 198 | pub fn symbol(tag: Tag) []const u8 { | |
| 198 | pub fn lexeme(tag: Tag) ?[]const u8 { | |
| 199 | 199 | return switch (tag) { |
| 200 | .Invalid => "Invalid", | |
| 200 | .Invalid, | |
| 201 | .Identifier, | |
| 202 | .StringLiteral, | |
| 203 | .MultilineStringLiteralLine, | |
| 204 | .CharLiteral, | |
| 205 | .Eof, | |
| 206 | .Builtin, | |
| 207 | .IntegerLiteral, | |
| 208 | .FloatLiteral, | |
| 209 | .DocComment, | |
| 210 | .ContainerDocComment, | |
| 211 | => null, | |
| 212 | ||
| 201 | 213 | .Invalid_ampersands => "&&", |
| 202 | 214 | .Invalid_periodasterisks => ".**", |
| 203 | .Identifier => "Identifier", | |
| 204 | .StringLiteral => "StringLiteral", | |
| 205 | .MultilineStringLiteralLine => "MultilineStringLiteralLine", | |
| 206 | .CharLiteral => "CharLiteral", | |
| 207 | .Eof => "Eof", | |
| 208 | .Builtin => "Builtin", | |
| 209 | .IntegerLiteral => "IntegerLiteral", | |
| 210 | .FloatLiteral => "FloatLiteral", | |
| 211 | .DocComment => "DocComment", | |
| 212 | .ContainerDocComment => "ContainerDocComment", | |
| 213 | ||
| 214 | 215 | .Bang => "!", |
| 215 | 216 | .Pipe => "|", |
| 216 | 217 | .PipePipe => "||", |
| ... | ... | @@ -319,6 +320,10 @@ pub const Token = struct { |
| 319 | 320 | .Keyword_while => "while", |
| 320 | 321 | }; |
| 321 | 322 | } |
| 323 | ||
| 324 | pub fn symbol(tag: Tag) []const u8 { | |
| 325 | return tag.lexeme() orelse @tagName(tag); | |
| 326 | } | |
| 322 | 327 | }; |
| 323 | 328 | }; |
| 324 | 329 |