diff --git a/parser_test.zig b/parser_test.zig index 22d7a46d13..14f388f098 100644 --- a/parser_test.zig +++ b/parser_test.zig @@ -541,6 +541,7 @@ fn testCanonical(source: [:0]const u8) !void { return testTransform(source, source); } + test "zig fmt: remove extra whitespace at start and end of file with comment between" { try testTransform( \\ @@ -568,20 +569,6 @@ test "zig fmt: tuple struct" { ); } -test "zig fmt: rewrite callconv(.@\"inline\") to the inline keyword" { - try testTransform( - \\fn foo() callconv(.@"inline") void {} - \\const bar: @import("std").builtin.CallingConvention = .@"inline"; - \\fn foo() callconv(bar) void {} - \\ - , - \\inline fn foo() void {} - \\const bar: @import("std").builtin.CallingConvention = .@"inline"; - \\fn foo() callconv(bar) void {} - \\ - ); -} - test "zig fmt: respect line breaks in struct field value declaration" { try testCanonical( \\const Foo = struct { @@ -624,13 +611,16 @@ test "zig fmt: respect line breaks before functions" { ); } -test "zig fmt: top-level for/while loop" { - try testCanonical( - \\for (foo) |_| foo +test "zig fmt: rewrite callconv(.@\"inline\") to the inline keyword" { + try testTransform( + \\fn foo() callconv(.@"inline") void {} + \\const bar: @import("std").builtin.CallingConvention = .@"inline"; + \\fn foo() callconv(bar) void {} \\ - ); - try testCanonical( - \\while (foo) |_| foo + , + \\inline fn foo() void {} + \\const bar: @import("std").builtin.CallingConvention = .@"inline"; + \\fn foo() callconv(bar) void {} \\ ); } @@ -759,6 +749,17 @@ test "zig fmt: top-level tuple function call type" { ); } +test "zig fmt: top-level for/while loop" { + try testCanonical( + \\for (foo) |_| foo + \\ + ); + try testCanonical( + \\while (foo) |_| foo + \\ + ); +} + test "zig fmt: top-level bare asterisk+identifier" { try testCanonical( \\*x @@ -1939,6 +1940,77 @@ test "zig fmt: 'zig fmt: on' indentation is unchanged" { ); } +test "zig fmt: pointer of unknown length" { + try testCanonical( + \\fn foo(ptr: [*]u8) void {} + \\ + ); +} + +test "zig fmt: spaces around slice operator" { + try testCanonical( + \\var a = b[c..d]; + \\var a = b[c..d :0]; + \\var a = b[c + 1 .. d]; + \\var a = b[c + 1 ..]; + \\var a = b[c .. d + 1]; + \\var a = b[c .. d + 1 :0]; + \\var a = b[c.a..d.e]; + \\var a = b[c.a..d.e :0]; + \\ + ); +} + +test "zig fmt: 2nd arg multiline string" { + try testCanonical( + \\comptime { + \\ cases.addAsm("hello world linux x86_64", + \\ \\.text + \\ , "Hello, world!\n"); + \\} + \\ + ); + try testTransform( + \\comptime { + \\ cases.addAsm("hello world linux x86_64", + \\ \\.text + \\ , "Hello, world!\n",); + \\} + , + \\comptime { + \\ cases.addAsm( + \\ "hello world linux x86_64", + \\ \\.text + \\ , + \\ "Hello, world!\n", + \\ ); + \\} + \\ + ); +} + +test "zig fmt: 2nd arg multiline string many args" { + try testCanonical( + \\comptime { + \\ cases.addAsm("hello world linux x86_64", + \\ \\.text + \\ , "Hello, world!\n", "Hello, world!\n"); + \\} + \\ + ); +} + +test "zig fmt: final arg multiline string" { + try testCanonical( + \\comptime { + \\ cases.addAsm("hello world linux x86_64", "Hello, world!\n", + \\ \\.text + \\ ); + \\} + \\ + ); +} + test "zig fmt: if condition wraps" { try testTransform( \\comptime { @@ -2065,77 +2137,6 @@ test "zig fmt: if condition has line break but must not wrap (no fn call comma)" ); } -test "zig fmt: pointer of unknown length" { - try testCanonical( - \\fn foo(ptr: [*]u8) void {} - \\ - ); -} - -test "zig fmt: spaces around slice operator" { - try testCanonical( - \\var a = b[c..d]; - \\var a = b[c..d :0]; - \\var a = b[c + 1 .. d]; - \\var a = b[c + 1 ..]; - \\var a = b[c .. d + 1]; - \\var a = b[c .. d + 1 :0]; - \\var a = b[c.a..d.e]; - \\var a = b[c.a..d.e :0]; - \\ - ); -} - -test "zig fmt: 2nd arg multiline string" { - try testCanonical( - \\comptime { - \\ cases.addAsm("hello world linux x86_64", - \\ \\.text - \\ , "Hello, world!\n"); - \\} - \\ - ); - try testTransform( - \\comptime { - \\ cases.addAsm("hello world linux x86_64", - \\ \\.text - \\ , "Hello, world!\n",); - \\} - , - \\comptime { - \\ cases.addAsm( - \\ "hello world linux x86_64", - \\ \\.text - \\ , - \\ "Hello, world!\n", - \\ ); - \\} - \\ - ); -} - -test "zig fmt: 2nd arg multiline string many args" { - try testCanonical( - \\comptime { - \\ cases.addAsm("hello world linux x86_64", - \\ \\.text - \\ , "Hello, world!\n", "Hello, world!\n"); - \\} - \\ - ); -} - -test "zig fmt: final arg multiline string" { - try testCanonical( - \\comptime { - \\ cases.addAsm("hello world linux x86_64", "Hello, world!\n", - \\ \\.text - \\ ); - \\} - \\ - ); -} - test "zig fmt: function call with multiline argument" { try testCanonical( \\comptime { @@ -2148,31 +2149,6 @@ test "zig fmt: function call with multiline argument" { ); } -test "zig fmt: switch comment before prong" { - try testCanonical( - \\comptime { - \\ switch (a) { - \\ // hi - \\ 0 => {}, - \\ } - \\} - \\ - ); -} - -test "zig fmt: switch comment after prong" { - try testCanonical( - \\comptime { - \\ switch (a) { - \\ 0, - \\ // hi - \\ => {}, - \\ } - \\} - \\ - ); -} - test "zig fmt: if-else with comment before else" { try testCanonical( \\comptime { @@ -2271,6 +2247,31 @@ test "zig fmt: enum decl with no trailing comma" { ); } +test "zig fmt: switch comment before prong" { + try testCanonical( + \\comptime { + \\ switch (a) { + \\ // hi + \\ 0 => {}, + \\ } + \\} + \\ + ); +} + +test "zig fmt: switch comment after prong" { + try testCanonical( + \\comptime { + \\ switch (a) { + \\ 0, + \\ // hi + \\ => {}, + \\ } + \\} + \\ + ); +} + test "zig fmt: struct literal no trailing comma" { try testTransform( \\const a = foo{ .x = 1, .y = 2 }; @@ -2577,6 +2578,15 @@ test "zig fmt: extra newlines at the end" { ); } +test "zig fmt: nested struct literal with one item" { + try testCanonical( + \\const a = foo{ + \\ .item = bar{ .a = b }, + \\}; + \\ + ); +} + test "zig fmt: switch cases trailing comma" { try testTransform( \\test "switch cases trailing comma"{ @@ -2720,6 +2730,17 @@ test "zig fmt: nested blocks" { ); } +test "zig fmt: block with same line comment after end brace" { + try testCanonical( + \\test { + \\ { + \\ const a = b; + \\ } // end of block + \\} + \\ + ); +} + test "zig fmt: statements with comment between" { try testCanonical( \\comptime { @@ -2750,216 +2771,6 @@ test "zig fmt: ptr deref operator and unwrap optional operator" { ); } -test "zig fmt: nested struct literal with one item" { - try testCanonical( - \\const a = foo{ - \\ .item = bar{ .a = b }, - \\}; - \\ - ); -} - -test "zig fmt: block with same line comment after end brace" { - try testCanonical( - \\test { - \\ { - \\ const a = b; - \\ } // end of block - \\} - \\ - ); -} - -test "zig fmt: comments before var decl in struct" { - try testCanonical( - \\const Foo = struct { - \\ /// comment - \\ bar: bool = true, - \\}; - \\ - ); -} - -test "zig fmt: comments before global variables" { - try testCanonical( - \\/// comment - \\var foo: i32 = undefined; - \\ - ); -} - -test "zig fmt: comments before test decl" { - try testCanonical( - \\/// top level doc comment - \\test "hi" {} - \\ - ); -} - -test "zig fmt: alignment" { - try testCanonical( - \\var foo: c_int align(1); - \\ - ); -} - -test "zig fmt: C main" { - try testCanonical( - \\fn main(argc: c_int, argv: **u8) c_int { - \\ const a = b; - \\} - \\ - ); -} - -test "zig fmt: return" { - try testCanonical( - \\fn foo(argc: c_int, argv: **u8) c_int { - \\ return 0; - \\} - \\ - \\fn bar() void { - \\ return; - \\} - \\ - ); -} - -test "zig fmt: call expression" { - try testCanonical( - \\test "test calls" { - \\ a(); - \\ a(1); - \\ a(1, 2); - \\ a(1, 2) + a(1, 2); - \\} - \\ - ); -} - -test "zig fmt: anytype type" { - try testCanonical( - \\fn print(args: anytype) @This() {} - \\ - ); -} - -test "zig fmt: arrays" { - try testCanonical( - \\test "arrays" { - \\ const a: [2]u32 = .{ 1, 2 }; - \\ const b = a ++ a; - \\ const c = a[0..]; - \\ _ = c; - \\} - \\ - ); -} - -test "zig fmt: container initializers" { - try testCanonical( - \\const a0 = []u8{}; - \\const a1 = []u8{1}; - \\const a2 = []u8{ - \\ 1, - \\ 2, - \\ 3, - \\ 4, - \\}; - \\const s0 = S{}; - \\const s1 = S{ .a = 1 }; - \\const s2 = S{ - \\ .a = 1, - \\ .b = 2, - \\}; - \\ - ); -} - -test "zig fmt: blocks" { - try testCanonical( - \\test { - \\ { - \\ const a = b; - \\ } - \\ const c = d; - \\} - \\ - ); -} - -test "zig fmt: defer" { - try testCanonical( - \\test "defer" { - \\ defer foo(); - \\ defer { - \\ bar(); - \\ } - \\} - \\ - ); -} - -test "zig fmt: comptime" { - try testCanonical( - \\fn foo() void { - \\ comptime { - \\ bar(); - \\ } - \\} - \\ - ); -} - -test "zig fmt: comptime block in container" { - try testCanonical( - \\const Foo = struct { - \\ comptime { - \\ @compileLog("hello comptime"); - \\ } - \\}; - \\ - ); -} - -test "zig fmt: comment after empty comment" { - try testCanonical( - \\// - \\/// A doc comment - \\const a = b; - \\ - ); -} - -test "zig fmt: comment after params" { - try testCanonical( - \\fn foo( - \\ a: i32, // comment - \\ b: i32, // comment - \\) void {} - \\ - ); -} - -test "zig fmt: container doc comments" { - try testCanonical( - \\//! tld 1 - \\//! tld 2 - \\//! tld 3 - \\const a = b; - \\ - ); -} - -test "zig fmt: decimal float literals with underscore separators" { - try testCanonical( - \\const x = 1_234_567.89_10_11; - \\const y = 1_234_567.89_10_11e1_213_14; - \\const z = 1_234_567; - \\ - ); -} - test "zig fmt: comment after if before another if" { try testCanonical( \\test "aoeu" { @@ -3151,6 +2962,151 @@ test "zig fmt: first line comment in struct initializer" { ); } +test "zig fmt: doc comments before struct field" { + try testCanonical( + \\pub const Allocator = struct { + \\ /// Allocate byte_count bytes and return them in a slice, with the + \\ /// slice's pointer aligned at least to alignment bytes. + \\ allocFn: fn () void, + \\}; + \\ + ); +} + +test "zig fmt: error set declaration" { + try testCanonical( + \\const E = error{ + \\ A, + \\ B, + \\ + \\ C, + \\}; + \\ + \\const Error = error{ + \\ /// no more memory + \\ OutOfMemory, + \\}; + \\ + \\const Error = error{ + \\ /// no more memory + \\ OutOfMemory, + \\ + \\ /// another + \\ Another, + \\ + \\ // end + \\}; + \\ + \\const Error = error{OutOfMemory}; + \\const Error = error{}; + \\ + \\const Error = error{ OutOfMemory, OutOfTime }; + \\ + ); +} + +test "zig fmt: union(enum(u32)) with assigned enum values" { + try testCanonical( + \\const MultipleChoice = union(enum(u32)) { + \\ A = 20, + \\ B = 40, + \\ C = 60, + \\ D = 1000, + \\}; + \\ + ); +} + +test "zig fmt: resume from suspend block" { + try testCanonical( + \\fn foo() void { + \\ suspend { + \\ resume @frame(); + \\ } + \\} + \\ + ); +} + +test "zig fmt: comments before error set decl" { + try testCanonical( + \\const UnexpectedError = error{ + \\ /// The Operating System returned an undocumented error code. + \\ Unexpected, + \\ // another + \\ Another, + \\ + \\ // in between + \\ + \\ // at end + \\}; + \\ + ); +} + +test "zig fmt: comments before switch prong" { + try testCanonical( + \\test "" { + \\ switch (err) { + \\ error.PathAlreadyExists => continue, + \\ + \\ // comment 1 + \\ + \\ // comment 2 + \\ else => return err, + \\ // at end + \\ } + \\} + \\ + ); +} + +test "zig fmt: comments before var decl in struct" { + try testCanonical( + \\const Foo = struct { + \\ /// comment + \\ bar: bool = true, + \\}; + \\ + ); +} + +test "zig fmt: array literal with 1 item on 1 line" { + try testCanonical( + \\var s = []const u64{0} ** 25; + \\ + ); +} + +test "zig fmt: comments before global variables" { + try testCanonical( + \\/// comment + \\var foo: i32 = undefined; + \\ + ); +} + +test "zig fmt: comments in statements" { + try testCanonical( + \\comptime { + \\ // a + \\ + \\ const x = 42; // b + \\ + \\ // c + \\} + \\ + ); +} + +test "zig fmt: comments before test decl" { + try testCanonical( + \\/// top level doc comment + \\test "hi" {} + \\ + ); +} + test "zig fmt: preserve spacing" { try testCanonical( \\const std = @import("std"); @@ -3212,6 +3168,35 @@ test "zig fmt: extern declaration" { ); } +test "zig fmt: alignment" { + try testCanonical( + \\var foo: c_int align(1); + \\ + ); +} + +test "zig fmt: C main" { + try testCanonical( + \\fn main(argc: c_int, argv: **u8) c_int { + \\ const a = b; + \\} + \\ + ); +} + +test "zig fmt: return" { + try testCanonical( + \\fn foo(argc: c_int, argv: **u8) c_int { + \\ return 0; + \\} + \\ + \\fn bar() void { + \\ return; + \\} + \\ + ); +} + test "zig fmt: function attributes" { try testCanonical( \\export fn foo() void {} @@ -3290,6 +3275,25 @@ test "zig fmt: prefix operators" { ); } +test "zig fmt: call expression" { + try testCanonical( + \\test "test calls" { + \\ a(); + \\ a(1); + \\ a(1, 2); + \\ a(1, 2) + a(1, 2); + \\} + \\ + ); +} + +test "zig fmt: anytype type" { + try testCanonical( + \\fn print(args: anytype) @This() {} + \\ + ); +} + test "zig fmt: functions" { try testCanonical( \\extern fn puts(s: *const u8) c_int; @@ -3425,125 +3429,6 @@ test "zig fmt: struct declaration" { ); } -test "zig fmt: error set declaration" { - try testCanonical( - \\const E = error{ - \\ A, - \\ B, - \\ - \\ C, - \\}; - \\ - \\const Error = error{ - \\ /// no more memory - \\ OutOfMemory, - \\}; - \\ - \\const Error = error{ - \\ /// no more memory - \\ OutOfMemory, - \\ - \\ /// another - \\ Another, - \\ - \\ // end - \\}; - \\ - \\const Error = error{OutOfMemory}; - \\const Error = error{}; - \\ - \\const Error = error{ OutOfMemory, OutOfTime }; - \\ - ); -} - -test "zig fmt: union(enum(u32)) with assigned enum values" { - try testCanonical( - \\const MultipleChoice = union(enum(u32)) { - \\ A = 20, - \\ B = 40, - \\ C = 60, - \\ D = 1000, - \\}; - \\ - ); -} - -test "zig fmt: resume from suspend block" { - try testCanonical( - \\fn foo() void { - \\ suspend { - \\ resume @frame(); - \\ } - \\} - \\ - ); -} - -test "zig fmt: comments before error set decl" { - try testCanonical( - \\const UnexpectedError = error{ - \\ /// The Operating System returned an undocumented error code. - \\ Unexpected, - \\ // another - \\ Another, - \\ - \\ // in between - \\ - \\ // at end - \\}; - \\ - ); -} - -test "zig fmt: comments before switch prong" { - try testCanonical( - \\test "" { - \\ switch (err) { - \\ error.PathAlreadyExists => continue, - \\ - \\ // comment 1 - \\ - \\ // comment 2 - \\ else => return err, - \\ // at end - \\ } - \\} - \\ - ); -} - -test "zig fmt: array literal with 1 item on 1 line" { - try testCanonical( - \\var s = []const u64{0} ** 25; - \\ - ); -} - -test "zig fmt: comments in statements" { - try testCanonical( - \\comptime { - \\ // a - \\ - \\ const x = 42; // b - \\ - \\ // c - \\} - \\ - ); -} - -test "zig fmt: doc comments before struct field" { - try testCanonical( - \\pub const Allocator = struct { - \\ /// Allocate byte_count bytes and return them in a slice, with the - \\ /// slice's pointer aligned at least to alignment bytes. - \\ allocFn: fn () void, - \\}; - \\ - ); -} - test "zig fmt: enum declaration" { try testCanonical( \\const E = enum { @@ -3612,6 +3497,38 @@ test "zig fmt: union declaration" { ); } +test "zig fmt: arrays" { + try testCanonical( + \\test "arrays" { + \\ const a: [2]u32 = .{ 1, 2 }; + \\ const b = a ++ a; + \\ const c = a[0..]; + \\ _ = c; + \\} + \\ + ); +} + +test "zig fmt: container initializers" { + try testCanonical( + \\const a0 = []u8{}; + \\const a1 = []u8{1}; + \\const a2 = []u8{ + \\ 1, + \\ 2, + \\ 3, + \\ 4, + \\}; + \\const s0 = S{}; + \\const s1 = S{ .a = 1 }; + \\const s2 = S{ + \\ .a = 1, + \\ .b = 2, + \\}; + \\ + ); +} + test "zig fmt: catch" { try testCanonical( \\test "catch" { @@ -3627,6 +3544,18 @@ test "zig fmt: catch" { ); } +test "zig fmt: blocks" { + try testCanonical( + \\test { + \\ { + \\ const a = b; + \\ } + \\ const c = d; + \\} + \\ + ); +} + test "zig fmt: switch" { try testCanonical( \\test "switch" { @@ -3682,8 +3611,6 @@ test "zig fmt: switch" { ); } - - test "zig fmt: for if" { try testCanonical( \\test { @@ -3883,6 +3810,77 @@ test "zig fmt: if" { ); } +test "zig fmt: defer" { + try testCanonical( + \\test "defer" { + \\ defer foo(); + \\ defer { + \\ bar(); + \\ } + \\} + \\ + ); +} + +test "zig fmt: comptime" { + try testCanonical( + \\fn foo() void { + \\ comptime { + \\ bar(); + \\ } + \\} + \\ + ); +} + +test "zig fmt: comptime block in container" { + try testCanonical( + \\const Foo = struct { + \\ comptime { + \\ @compileLog("hello comptime"); + \\ } + \\}; + \\ + ); +} + +test "zig fmt: comment after empty comment" { + try testCanonical( + \\// + \\/// A doc comment + \\const a = b; + \\ + ); +} + +test "zig fmt: comment after params" { + try testCanonical( + \\fn foo( + \\ a: i32, // comment + \\ b: i32, // comment + \\) void {} + \\ + ); +} + +test "zig fmt: container doc comments" { + try testCanonical( + \\//! tld 1 + \\//! tld 2 + \\//! tld 3 + \\const a = b; + \\ + ); +} + +test "zig fmt: decimal float literals with underscore separators" { + try testCanonical( + \\const x = 1_234_567.89_10_11; + \\const y = 1_234_567.89_10_11e1_213_14; + \\const z = 1_234_567; + \\ + ); +} test "Ast header smoke test" { try std.testing.expectEqual(zigNode(c.AST_NODE_IF), Ast.Node.Tag.@"if");