authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-11 22:38:59+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-11 15:49:49-08:00
logfaa3fa65ac89b774b26bdd0ea4ac70861b29d0b4
treef3fe6d80be3190224458b711f7c5ffcf90c7c0da
parentb6448a533d4465c226b7b8613806ff0673261d6a

zig fmt: implement line comments


2 files changed, 595 insertions(+), 660 deletions(-)

lib/std/zig/parser_test.zig+531-558
......@@ -663,7 +663,9 @@ test "zig fmt: anon list literal 3 element comma" {
663663 \\test {
664664 \\ const x = .{
665665 \\ a,
666 \\ // foo
666667 \\ b,
668 \\
667669 \\ c,
668670 \\ };
669671 \\}
......@@ -874,20 +876,20 @@ test "zig fmt: enum literal" {
874876 );
875877}
876878
877//test "zig fmt: enum literal inside array literal" {
878// try testCanonical(
879// \\test "enums in arrays" {
880// \\ var colors = []Color{.Green};
881// \\ colors = []Colors{ .Green, .Cyan };
882// \\ colors = []Colors{
883// \\ .Grey,
884// \\ .Green,
885// \\ .Cyan,
886// \\ };
887// \\}
888// \\
889// );
890//}
879test "zig fmt: enum literal inside array literal" {
880 try testCanonical(
881 \\test "enums in arrays" {
882 \\ var colors = []Color{.Green};
883 \\ colors = []Colors{ .Green, .Cyan };
884 \\ colors = []Colors{
885 \\ .Grey,
886 \\ .Green,
887 \\ .Cyan,
888 \\ };
889 \\}
890 \\
891 );
892}
891893
892894test "zig fmt: character literal larger than u8" {
893895 try testCanonical(
......@@ -954,56 +956,56 @@ test "zig fmt: linksection" {
954956// \\
955957// );
956958//}
957//
958//test "zig fmt: correctly space struct fields with doc comments" {
959// try testTransform(
960// \\pub const S = struct {
961// \\ /// A
962// \\ a: u8,
963// \\ /// B
964// \\ /// B (cont)
965// \\ b: u8,
966// \\
967// \\
968// \\ /// C
969// \\ c: u8,
970// \\};
971// \\
972// ,
973// \\pub const S = struct {
974// \\ /// A
975// \\ a: u8,
976// \\ /// B
977// \\ /// B (cont)
978// \\ b: u8,
979// \\
980// \\ /// C
981// \\ c: u8,
982// \\};
983// \\
984// );
985//}
986//
987//test "zig fmt: doc comments on param decl" {
988// try testCanonical(
989// \\pub const Allocator = struct {
990// \\ shrinkFn: fn (
991// \\ self: *Allocator,
992// \\ /// Guaranteed to be the same as what was returned from most recent call to
993// \\ /// `allocFn`, `reallocFn`, or `shrinkFn`.
994// \\ old_mem: []u8,
995// \\ /// Guaranteed to be the same as what was returned from most recent call to
996// \\ /// `allocFn`, `reallocFn`, or `shrinkFn`.
997// \\ old_alignment: u29,
998// \\ /// Guaranteed to be less than or equal to `old_mem.len`.
999// \\ new_byte_count: usize,
1000// \\ /// Guaranteed to be less than or equal to `old_alignment`.
1001// \\ new_alignment: u29,
1002// \\ ) []u8,
1003// \\};
1004// \\
1005// );
1006//}
959
960test "zig fmt: correctly space struct fields with doc comments" {
961 try testTransform(
962 \\pub const S = struct {
963 \\ /// A
964 \\ a: u8,
965 \\ /// B
966 \\ /// B (cont)
967 \\ b: u8,
968 \\
969 \\
970 \\ /// C
971 \\ c: u8,
972 \\};
973 \\
974 ,
975 \\pub const S = struct {
976 \\ /// A
977 \\ a: u8,
978 \\ /// B
979 \\ /// B (cont)
980 \\ b: u8,
981 \\
982 \\ /// C
983 \\ c: u8,
984 \\};
985 \\
986 );
987}
988
989test "zig fmt: doc comments on param decl" {
990 try testCanonical(
991 \\pub const Allocator = struct {
992 \\ shrinkFn: fn (
993 \\ self: *Allocator,
994 \\ /// Guaranteed to be the same as what was returned from most recent call to
995 \\ /// `allocFn`, `reallocFn`, or `shrinkFn`.
996 \\ old_mem: []u8,
997 \\ /// Guaranteed to be the same as what was returned from most recent call to
998 \\ /// `allocFn`, `reallocFn`, or `shrinkFn`.
999 \\ old_alignment: u29,
1000 \\ /// Guaranteed to be less than or equal to `old_mem.len`.
1001 \\ new_byte_count: usize,
1002 \\ /// Guaranteed to be less than or equal to `old_alignment`.
1003 \\ new_alignment: u29,
1004 \\ ) []u8,
1005 \\};
1006 \\
1007 );
1008}
10071009
10081010test "zig fmt: aligned struct field" {
10091011 try testCanonical(
......@@ -1142,13 +1144,13 @@ test "zig fmt: aligned struct field" {
11421144// \\
11431145// );
11441146//}
1145//
1146//test "zig fmt: pointer of unknown length" {
1147// try testCanonical(
1148// \\fn foo(ptr: [*]u8) void {}
1149// \\
1150// );
1151//}
1147
1148test "zig fmt: pointer of unknown length" {
1149 try testCanonical(
1150 \\fn foo(ptr: [*]u8) void {}
1151 \\
1152 );
1153}
11521154
11531155test "zig fmt: spaces around slice operator" {
11541156 try testCanonical(
......@@ -1370,25 +1372,25 @@ test "zig fmt: async call in if condition" {
13701372// \\
13711373// );
13721374//}
1373//
1374//test "zig fmt: if-else with comment before else" {
1375// try testCanonical(
1376// \\comptime {
1377// \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
1378// \\ if ((hx & 0x7fffffff) != 0x7f800000) {
1379// \\ return Complex(f32).new(y - y, y - y);
1380// \\ } // cexp(-inf +- i inf|nan) = 0 + i0
1381// \\ else if (hx & 0x80000000 != 0) {
1382// \\ return Complex(f32).new(0, 0);
1383// \\ } // cexp(+inf +- i inf|nan) = inf + i nan
1384// \\ else {
1385// \\ return Complex(f32).new(x, y - y);
1386// \\ }
1387// \\}
1388// \\
1389// );
1390//}
1391//
1375
1376test "zig fmt: if-else with comment before else" {
1377 try testCanonical(
1378 \\comptime {
1379 \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
1380 \\ if ((hx & 0x7fffffff) != 0x7f800000) {
1381 \\ return Complex(f32).new(y - y, y - y);
1382 \\ } // cexp(-inf +- i inf|nan) = 0 + i0
1383 \\ else if (hx & 0x80000000 != 0) {
1384 \\ return Complex(f32).new(0, 0);
1385 \\ } // cexp(+inf +- i inf|nan) = inf + i nan
1386 \\ else {
1387 \\ return Complex(f32).new(x, y - y);
1388 \\ }
1389 \\}
1390 \\
1391 );
1392}
1393
13921394//test "zig fmt: if nested" {
13931395// try testCanonical(
13941396// \\pub fn foo() void {
......@@ -1467,17 +1469,17 @@ test "zig fmt: enum decl with no trailing comma" {
14671469 );
14681470}
14691471
1470//test "zig fmt: switch comment before prong" {
1471// try testCanonical(
1472// \\comptime {
1473// \\ switch (a) {
1474// \\ // hi
1475// \\ 0 => {},
1476// \\ }
1477// \\}
1478// \\
1479// );
1480//}
1472test "zig fmt: switch comment before prong" {
1473 try testCanonical(
1474 \\comptime {
1475 \\ switch (a) {
1476 \\ // hi
1477 \\ 0 => {},
1478 \\ }
1479 \\}
1480 \\
1481 );
1482}
14811483
14821484test "zig fmt: struct literal no trailing comma" {
14831485 try testTransform(
......@@ -1709,17 +1711,17 @@ test "zig fmt: multi line arguments without last comma" {
17091711 );
17101712}
17111713
1712//test "zig fmt: empty block with only comment" {
1713// try testCanonical(
1714// \\comptime {
1715// \\ {
1716// \\ // comment
1717// \\ }
1718// \\}
1719// \\
1720// );
1721//}
1722//
1714test "zig fmt: empty block with only comment" {
1715 try testCanonical(
1716 \\comptime {
1717 \\ {
1718 \\ // comment
1719 \\ }
1720 \\}
1721 \\
1722 );
1723}
1724
17231725//test "zig fmt: no trailing comma on struct decl" {
17241726// try testCanonical(
17251727// \\const RoundParam = struct {
......@@ -1781,15 +1783,15 @@ test "zig fmt: extra newlines at the end" {
17811783// \\
17821784// );
17831785//}
1784//
1785//test "zig fmt: nested struct literal with one item" {
1786// try testCanonical(
1787// \\const a = foo{
1788// \\ .item = bar{ .a = b },
1789// \\};
1790// \\
1791// );
1792//}
1786
1787test "zig fmt: nested struct literal with one item" {
1788 try testCanonical(
1789 \\const a = foo{
1790 \\ .item = bar{ .a = b },
1791 \\};
1792 \\
1793 );
1794}
17931795
17941796test "zig fmt: switch cases trailing comma" {
17951797 try testTransform(
......@@ -1848,26 +1850,26 @@ test "zig fmt: slice align" {
18481850// \\
18491851// );
18501852//}
1851//
1852//test "zig fmt: first thing in file is line comment" {
1853// try testCanonical(
1854// \\// Introspection and determination of system libraries needed by zig.
1855// \\
1856// \\// Introspection and determination of system libraries needed by zig.
1857// \\
1858// \\const std = @import("std");
1859// \\
1860// );
1861//}
1862//
1863//test "zig fmt: line comment after doc comment" {
1864// try testCanonical(
1865// \\/// doc comment
1866// \\// line comment
1867// \\fn foo() void {}
1868// \\
1869// );
1870//}
1853
1854test "zig fmt: first thing in file is line comment" {
1855 try testCanonical(
1856 \\// Introspection and determination of system libraries needed by zig.
1857 \\
1858 \\// Introspection and determination of system libraries needed by zig.
1859 \\
1860 \\const std = @import("std");
1861 \\
1862 );
1863}
1864
1865test "zig fmt: line comment after doc comment" {
1866 try testCanonical(
1867 \\/// doc comment
1868 \\// line comment
1869 \\fn foo() void {}
1870 \\
1871 );
1872}
18711873
18721874test "zig fmt: bit field alignment" {
18731875 try testCanonical(
......@@ -1928,27 +1930,27 @@ test "zig fmt: nested blocks" {
19281930 );
19291931}
19301932
1931//test "zig fmt: block with same line comment after end brace" {
1932// try testCanonical(
1933// \\comptime {
1934// \\ {
1935// \\ b();
1936// \\ } // comment
1937// \\}
1938// \\
1939// );
1940//}
1941//
1942//test "zig fmt: statements with comment between" {
1943// try testCanonical(
1944// \\comptime {
1945// \\ a = b;
1946// \\ // comment
1947// \\ a = b;
1948// \\}
1949// \\
1950// );
1951//}
1933test "zig fmt: block with same line comment after end brace" {
1934 try testCanonical(
1935 \\comptime {
1936 \\ {
1937 \\ b();
1938 \\ } // comment
1939 \\}
1940 \\
1941 );
1942}
1943
1944test "zig fmt: statements with comment between" {
1945 try testCanonical(
1946 \\comptime {
1947 \\ a = b;
1948 \\ // comment
1949 \\ a = b;
1950 \\}
1951 \\
1952 );
1953}
19521954
19531955test "zig fmt: statements with empty line between" {
19541956 try testCanonical(
......@@ -1969,60 +1971,60 @@ test "zig fmt: ptr deref operator and unwrap optional operator" {
19691971 );
19701972}
19711973
1972//test "zig fmt: comment after if before another if" {
1973// try testCanonical(
1974// \\test "aoeu" {
1975// \\ // comment
1976// \\ if (x) {
1977// \\ bar();
1978// \\ }
1979// \\}
1980// \\
1981// \\test "aoeu" {
1982// \\ if (x) {
1983// \\ foo();
1984// \\ }
1985// \\ // comment
1986// \\ if (x) {
1987// \\ bar();
1988// \\ }
1989// \\}
1990// \\
1991// );
1992//}
1993//
1994//test "zig fmt: line comment between if block and else keyword" {
1995// try testCanonical(
1996// \\test "aoeu" {
1997// \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
1998// \\ if ((hx & 0x7fffffff) != 0x7f800000) {
1999// \\ return Complex(f32).new(y - y, y - y);
2000// \\ }
2001// \\ // cexp(-inf +- i inf|nan) = 0 + i0
2002// \\ else if (hx & 0x80000000 != 0) {
2003// \\ return Complex(f32).new(0, 0);
2004// \\ }
2005// \\ // cexp(+inf +- i inf|nan) = inf + i nan
2006// \\ // another comment
2007// \\ else {
2008// \\ return Complex(f32).new(x, y - y);
2009// \\ }
2010// \\}
2011// \\
2012// );
2013//}
2014//
2015//test "zig fmt: same line comments in expression" {
2016// try testCanonical(
2017// \\test "aoeu" {
2018// \\ const x = ( // a
2019// \\ 0 // b
2020// \\ ); // c
2021// \\}
2022// \\
2023// );
2024//}
2025//
1974test "zig fmt: comment after if before another if" {
1975 try testCanonical(
1976 \\test "aoeu" {
1977 \\ // comment
1978 \\ if (x) {
1979 \\ bar();
1980 \\ }
1981 \\}
1982 \\
1983 \\test "aoeu" {
1984 \\ if (x) {
1985 \\ foo();
1986 \\ }
1987 \\ // comment
1988 \\ if (x) {
1989 \\ bar();
1990 \\ }
1991 \\}
1992 \\
1993 );
1994}
1995
1996test "zig fmt: line comment between if block and else keyword" {
1997 try testCanonical(
1998 \\test "aoeu" {
1999 \\ // cexp(finite|nan +- i inf|nan) = nan + i nan
2000 \\ if ((hx & 0x7fffffff) != 0x7f800000) {
2001 \\ return Complex(f32).new(y - y, y - y);
2002 \\ }
2003 \\ // cexp(-inf +- i inf|nan) = 0 + i0
2004 \\ else if (hx & 0x80000000 != 0) {
2005 \\ return Complex(f32).new(0, 0);
2006 \\ }
2007 \\ // cexp(+inf +- i inf|nan) = inf + i nan
2008 \\ // another comment
2009 \\ else {
2010 \\ return Complex(f32).new(x, y - y);
2011 \\ }
2012 \\}
2013 \\
2014 );
2015}
2016
2017test "zig fmt: same line comments in expression" {
2018 try testCanonical(
2019 \\test "aoeu" {
2020 \\ const x = ( // a
2021 \\ 0 // b
2022 \\ ); // c
2023 \\}
2024 \\
2025 );
2026}
2027
20262028//test "zig fmt: add comma on last switch prong" {
20272029// try testTransform(
20282030// \\test "aoeu" {
......@@ -2051,127 +2053,126 @@ test "zig fmt: ptr deref operator and unwrap optional operator" {
20512053// \\
20522054// );
20532055//}
2054//
2055//test "zig fmt: same-line comment after a statement" {
2056// try testCanonical(
2057// \\test "" {
2058// \\ a = b;
2059// \\ debug.assert(H.digest_size <= H.block_size); // HMAC makes this assumption
2060// \\ a = b;
2061// \\}
2062// \\
2063// );
2064//}
2065//
2066//test "zig fmt: same-line comment after var decl in struct" {
2067// try testCanonical(
2068// \\pub const vfs_cap_data = extern struct {
2069// \\ const Data = struct {}; // when on disk.
2070// \\};
2071// \\
2072// );
2073//}
2074//
2075//test "zig fmt: same-line comment after field decl" {
2076// try testCanonical(
2077// \\pub const dirent = extern struct {
2078// \\ d_name: u8,
2079// \\ d_name: u8, // comment 1
2080// \\ d_name: u8,
2081// \\ d_name: u8, // comment 2
2082// \\ d_name: u8,
2083// \\};
2084// \\
2085// );
2086//}
2087//
2088//test "zig fmt: same-line comment after switch prong" {
2089// try testCanonical(
2090// \\test "" {
2091// \\ switch (err) {
2092// \\ error.PathAlreadyExists => {}, // comment 2
2093// \\ else => return err, // comment 1
2094// \\ }
2095// \\}
2096// \\
2097// );
2098//}
2099//
2100//test "zig fmt: same-line comment after non-block if expression" {
2101// try testCanonical(
2102// \\comptime {
2103// \\ if (sr > n_uword_bits - 1) // d > r
2104// \\ return 0;
2105// \\}
2106// \\
2107// );
2108//}
2109//
2110//test "zig fmt: same-line comment on comptime expression" {
2111// try testCanonical(
2112// \\test "" {
2113// \\ comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
2114// \\}
2115// \\
2116// );
2117//}
21182056
2119test "zig fmt: switch with empty body" {
2057test "zig fmt: same-line comment after a statement" {
2058 try testCanonical(
2059 \\test "" {
2060 \\ a = b;
2061 \\ debug.assert(H.digest_size <= H.block_size); // HMAC makes this assumption
2062 \\ a = b;
2063 \\}
2064 \\
2065 );
2066}
2067
2068test "zig fmt: same-line comment after var decl in struct" {
2069 try testCanonical(
2070 \\pub const vfs_cap_data = extern struct {
2071 \\ const Data = struct {}; // when on disk.
2072 \\};
2073 \\
2074 );
2075}
2076
2077test "zig fmt: same-line comment after field decl" {
2078 try testCanonical(
2079 \\pub const dirent = extern struct {
2080 \\ d_name: u8,
2081 \\ d_name: u8, // comment 1
2082 \\ d_name: u8,
2083 \\ d_name: u8, // comment 2
2084 \\ d_name: u8,
2085 \\};
2086 \\
2087 );
2088}
2089
2090test "zig fmt: same-line comment after switch prong" {
2091 try testCanonical(
2092 \\test "" {
2093 \\ switch (err) {
2094 \\ error.PathAlreadyExists => {}, // comment 2
2095 \\ else => return err, // comment 1
2096 \\ }
2097 \\}
2098 \\
2099 );
2100}
2101
2102test "zig fmt: same-line comment after non-block if expression" {
2103 try testCanonical(
2104 \\comptime {
2105 \\ if (sr > n_uword_bits - 1) // d > r
2106 \\ return 0;
2107 \\}
2108 \\
2109 );
2110}
2111
2112test "zig fmt: same-line comment on comptime expression" {
2113 try testCanonical(
2114 \\test "" {
2115 \\ comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
2116 \\}
2117 \\
2118 );
2119}
2120
2121test "zig fmt: switch with empty body" {
2122 try testCanonical(
2123 \\test "" {
2124 \\ foo() catch |err| switch (err) {};
2125 \\}
2126 \\
2127 );
2128}
2129
2130test "zig fmt: line comments in struct initializer" {
2131 try testCanonical(
2132 \\fn foo() void {
2133 \\ return Self{
2134 \\ .a = b,
2135 \\
2136 \\ // Initialize these two fields to buffer_size so that
2137 \\ // in `readFn` we treat the state as being able to read
2138 \\ .start_index = buffer_size,
2139 \\ .end_index = buffer_size,
2140 \\
2141 \\ // middle
2142 \\
2143 \\ .a = b,
2144 \\
2145 \\ // end
2146 \\ };
2147 \\}
2148 \\
2149 );
2150}
2151
2152test "zig fmt: first line comment in struct initializer" {
21202153 try testCanonical(
2121 \\test "" {
2122 \\ foo() catch |err| switch (err) {};
2154 \\pub fn acquire(self: *Self) HeldLock {
2155 \\ return HeldLock{
2156 \\ // guaranteed allocation elision
2157 \\ .held = self.lock.acquire(),
2158 \\ .value = &self.private_data,
2159 \\ };
21232160 \\}
21242161 \\
21252162 );
21262163}
21272164
2128//test "zig fmt: line comments in struct initializer" {
2129// try testCanonical(
2130// \\fn foo() void {
2131// \\ return Self{
2132// \\ .a = b,
2133// \\
2134// \\ // Initialize these two fields to buffer_size so that
2135// \\ // in `readFn` we treat the state as being able to read
2136// \\ .start_index = buffer_size,
2137// \\ .end_index = buffer_size,
2138// \\
2139// \\ // middle
2140// \\
2141// \\ .a = b,
2142// \\
2143// \\ // end
2144// \\ };
2145// \\}
2146// \\
2147// );
2148//}
2149//
2150//test "zig fmt: first line comment in struct initializer" {
2151// try testCanonical(
2152// \\pub fn acquire(self: *Self) HeldLock {
2153// \\ return HeldLock{
2154// \\ // guaranteed allocation elision
2155// \\ .held = self.lock.acquire(),
2156// \\ .value = &self.private_data,
2157// \\ };
2158// \\}
2159// \\
2160// );
2161//}
2162//
2163//test "zig fmt: doc comments before struct field" {
2164// try testCanonical(
2165// \\pub const Allocator = struct {
2166// \\ /// Allocate byte_count bytes and return them in a slice, with the
2167// \\ /// slice's pointer aligned at least to alignment bytes.
2168// \\ allocFn: fn () void,
2169// \\};
2170// \\
2171// );
2172//}
2165test "zig fmt: doc comments before struct field" {
2166 try testCanonical(
2167 \\pub const Allocator = struct {
2168 \\ /// Allocate byte_count bytes and return them in a slice, with the
2169 \\ /// slice's pointer aligned at least to alignment bytes.
2170 \\ allocFn: fn () void,
2171 \\};
2172 \\
2173 );
2174}
21732175
2174// TODO: replace this with the next test case when possible
21752176test "zig fmt: error set declaration" {
21762177 try testCanonical(
21772178 \\const E = error{
......@@ -2180,58 +2181,30 @@ test "zig fmt: error set declaration" {
21802181 \\
21812182 \\ C,
21822183 \\};
2184 \\
21832185 \\const Error = error{
21842186 \\ /// no more memory
21852187 \\ OutOfMemory,
21862188 \\};
2189 \\
21872190 \\const Error = error{
21882191 \\ /// no more memory
21892192 \\ OutOfMemory,
21902193 \\
21912194 \\ /// another
21922195 \\ Another,
2193 \\ /// and one more
2194 \\ Another,
2196 \\
2197 \\ // end
21952198 \\};
2199 \\
21962200 \\const Error = error{OutOfMemory};
21972201 \\const Error = error{};
2202 \\
21982203 \\const Error = error{ OutOfMemory, OutOfTime };
21992204 \\
22002205 );
22012206}
22022207
2203//test "zig fmt: error set declaration" {
2204// try testCanonical(
2205// \\const E = error{
2206// \\ A,
2207// \\ B,
2208// \\
2209// \\ C,
2210// \\};
2211// \\
2212// \\const Error = error{
2213// \\ /// no more memory
2214// \\ OutOfMemory,
2215// \\};
2216// \\
2217// \\const Error = error{
2218// \\ /// no more memory
2219// \\ OutOfMemory,
2220// \\
2221// \\ /// another
2222// \\ Another,
2223// \\
2224// \\ // end
2225// \\};
2226// \\
2227// \\const Error = error{OutOfMemory};
2228// \\const Error = error{};
2229// \\
2230// \\const Error = error{ OutOfMemory, OutOfTime };
2231// \\
2232// );
2233//}
2234
22352208test "zig fmt: union(enum(u32)) with assigned enum values" {
22362209 try testCanonical(
22372210 \\const MultipleChoice = union(enum(u32)) {
......@@ -2255,110 +2228,110 @@ test "zig fmt: resume from suspend block" {
22552228 );
22562229}
22572230
2258//test "zig fmt: comments before error set decl" {
2259// try testCanonical(
2260// \\const UnexpectedError = error{
2261// \\ /// The Operating System returned an undocumented error code.
2262// \\ Unexpected,
2263// \\ // another
2264// \\ Another,
2265// \\
2266// \\ // in between
2267// \\
2268// \\ // at end
2269// \\};
2270// \\
2271// );
2272//}
2273//
2274//test "zig fmt: comments before switch prong" {
2275// try testCanonical(
2276// \\test "" {
2277// \\ switch (err) {
2278// \\ error.PathAlreadyExists => continue,
2279// \\
2280// \\ // comment 1
2281// \\
2282// \\ // comment 2
2283// \\ else => return err,
2284// \\ // at end
2285// \\ }
2286// \\}
2287// \\
2288// );
2289//}
2290//
2291//test "zig fmt: comments before var decl in struct" {
2292// try testCanonical(
2293// \\pub const vfs_cap_data = extern struct {
2294// \\ // All of these are mandated as little endian
2295// \\ // when on disk.
2296// \\ const Data = struct {
2297// \\ permitted: u32,
2298// \\ inheritable: u32,
2299// \\ };
2300// \\
2301// \\ // in between
2302// \\
2303// \\ /// All of these are mandated as little endian
2304// \\ /// when on disk.
2305// \\ const Data = struct {
2306// \\ permitted: u32,
2307// \\ inheritable: u32,
2308// \\ };
2309// \\
2310// \\ // at end
2311// \\};
2312// \\
2313// );
2314//}
2315//
2316//test "zig fmt: array literal with 1 item on 1 line" {
2317// try testCanonical(
2318// \\var s = []const u64{0} ** 25;
2319// \\
2320// );
2321//}
2322//
2323//test "zig fmt: comments before global variables" {
2324// try testCanonical(
2325// \\/// Foo copies keys and values before they go into the map, and
2326// \\/// frees them when they get removed.
2327// \\pub const Foo = struct {};
2328// \\
2329// );
2330//}
2331//
2332//test "zig fmt: comments in statements" {
2333// try testCanonical(
2334// \\test "std" {
2335// \\ // statement comment
2336// \\ _ = @import("foo/bar.zig");
2337// \\
2338// \\ // middle
2339// \\ // middle2
2340// \\
2341// \\ // end
2342// \\}
2343// \\
2344// );
2345//}
2346//
2347//test "zig fmt: comments before test decl" {
2348// try testCanonical(
2349// \\/// top level doc comment
2350// \\test "hi" {}
2351// \\
2352// \\// top level normal comment
2353// \\test "hi" {}
2354// \\
2355// \\// middle
2356// \\
2357// \\// end
2358// \\
2359// );
2360//}
2361//
2231test "zig fmt: comments before error set decl" {
2232 try testCanonical(
2233 \\const UnexpectedError = error{
2234 \\ /// The Operating System returned an undocumented error code.
2235 \\ Unexpected,
2236 \\ // another
2237 \\ Another,
2238 \\
2239 \\ // in between
2240 \\
2241 \\ // at end
2242 \\};
2243 \\
2244 );
2245}
2246
2247test "zig fmt: comments before switch prong" {
2248 try testCanonical(
2249 \\test "" {
2250 \\ switch (err) {
2251 \\ error.PathAlreadyExists => continue,
2252 \\
2253 \\ // comment 1
2254 \\
2255 \\ // comment 2
2256 \\ else => return err,
2257 \\ // at end
2258 \\ }
2259 \\}
2260 \\
2261 );
2262}
2263
2264test "zig fmt: comments before var decl in struct" {
2265 try testCanonical(
2266 \\pub const vfs_cap_data = extern struct {
2267 \\ // All of these are mandated as little endian
2268 \\ // when on disk.
2269 \\ const Data = struct {
2270 \\ permitted: u32,
2271 \\ inheritable: u32,
2272 \\ };
2273 \\
2274 \\ // in between
2275 \\
2276 \\ /// All of these are mandated as little endian
2277 \\ /// when on disk.
2278 \\ const Data = struct {
2279 \\ permitted: u32,
2280 \\ inheritable: u32,
2281 \\ };
2282 \\
2283 \\ // at end
2284 \\};
2285 \\
2286 );
2287}
2288
2289test "zig fmt: array literal with 1 item on 1 line" {
2290 try testCanonical(
2291 \\var s = []const u64{0} ** 25;
2292 \\
2293 );
2294}
2295
2296test "zig fmt: comments before global variables" {
2297 try testCanonical(
2298 \\/// Foo copies keys and values before they go into the map, and
2299 \\/// frees them when they get removed.
2300 \\pub const Foo = struct {};
2301 \\
2302 );
2303}
2304
2305test "zig fmt: comments in statements" {
2306 try testCanonical(
2307 \\test "std" {
2308 \\ // statement comment
2309 \\ _ = @import("foo/bar.zig");
2310 \\
2311 \\ // middle
2312 \\ // middle2
2313 \\
2314 \\ // end
2315 \\}
2316 \\
2317 );
2318}
2319
2320test "zig fmt: comments before test decl" {
2321 try testCanonical(
2322 \\/// top level doc comment
2323 \\test "hi" {}
2324 \\
2325 \\// top level normal comment
2326 \\test "hi" {}
2327 \\
2328 \\// middle
2329 \\
2330 \\// end
2331 \\
2332 );
2333}
2334
23622335//test "zig fmt: preserve spacing" {
23632336// try testCanonical(
23642337// \\const std = @import("std");
......@@ -2373,7 +2346,7 @@ test "zig fmt: resume from suspend block" {
23732346// \\
23742347// );
23752348//}
2376//
2349
23772350//test "zig fmt: return types" {
23782351// try testCanonical(
23792352// \\pub fn main() !void {}
......@@ -2798,43 +2771,43 @@ test "zig fmt: union declaration" {
27982771 );
27992772}
28002773
2801//test "zig fmt: arrays" {
2802// try testCanonical(
2803// \\test "test array" {
2804// \\ const a: [2]u8 = [2]u8{
2805// \\ 1,
2806// \\ 2,
2807// \\ };
2808// \\ const a: [2]u8 = []u8{
2809// \\ 1,
2810// \\ 2,
2811// \\ };
2812// \\ const a: [0]u8 = []u8{};
2813// \\ const x: [4:0]u8 = undefined;
2814// \\}
2815// \\
2816// );
2817//}
2774test "zig fmt: arrays" {
2775 try testCanonical(
2776 \\test "test array" {
2777 \\ const a: [2]u8 = [2]u8{
2778 \\ 1,
2779 \\ 2,
2780 \\ };
2781 \\ const a: [2]u8 = []u8{
2782 \\ 1,
2783 \\ 2,
2784 \\ };
2785 \\ const a: [0]u8 = []u8{};
2786 \\ const x: [4:0]u8 = undefined;
2787 \\}
2788 \\
2789 );
2790}
28182791
2819//test "zig fmt: container initializers" {
2820// try testCanonical(
2821// \\const a0 = []u8{};
2822// \\const a1 = []u8{1};
2823// \\const a2 = []u8{
2824// \\ 1,
2825// \\ 2,
2826// \\ 3,
2827// \\ 4,
2828// \\};
2829// \\const s0 = S{};
2830// \\const s1 = S{ .a = 1 };
2831// \\const s2 = S{
2832// \\ .a = 1,
2833// \\ .b = 2,
2834// \\};
2835// \\
2836// );
2837//}
2792test "zig fmt: container initializers" {
2793 try testCanonical(
2794 \\const a0 = []u8{};
2795 \\const a1 = []u8{1};
2796 \\const a2 = []u8{
2797 \\ 1,
2798 \\ 2,
2799 \\ 3,
2800 \\ 4,
2801 \\};
2802 \\const s0 = S{};
2803 \\const s1 = S{ .a = 1 };
2804 \\const s2 = S{
2805 \\ .a = 1,
2806 \\ .b = 2,
2807 \\};
2808 \\
2809 );
2810}
28382811
28392812test "zig fmt: catch" {
28402813 try testCanonical(
......@@ -3563,62 +3536,62 @@ test "zig fmt: integer literals with underscore separators" {
35633536 );
35643537}
35653538
3566//test "zig fmt: hex literals with underscore separators" {
3567// try testTransform(
3568// \\pub fn orMask(a: [ 1_000 ]u64, b: [ 1_000] u64) [1_000]u64 {
3569// \\ var c: [1_000]u64 = [1]u64{ 0xFFFF_FFFF_FFFF_FFFF}**1_000;
3570// \\ for (c [ 0_0 .. ]) |_, i| {
3571// \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA;
3572// \\ }
3573// \\ return c;
3574// \\}
3575// \\
3576// \\
3577// ,
3578// \\pub fn orMask(a: [1_000]u64, b: [1_000]u64) [1_000]u64 {
3579// \\ var c: [1_000]u64 = [1]u64{0xFFFF_FFFF_FFFF_FFFF} ** 1_000;
3580// \\ for (c[0_0..]) |_, i| {
3581// \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA;
3582// \\ }
3583// \\ return c;
3584// \\}
3585// \\
3586// );
3587//}
3539test "zig fmt: hex literals with underscore separators" {
3540 try testTransform(
3541 \\pub fn orMask(a: [ 1_000 ]u64, b: [ 1_000] u64) [1_000]u64 {
3542 \\ var c: [1_000]u64 = [1]u64{ 0xFFFF_FFFF_FFFF_FFFF}**1_000;
3543 \\ for (c [ 0_0 .. ]) |_, i| {
3544 \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA;
3545 \\ }
3546 \\ return c;
3547 \\}
3548 \\
3549 \\
3550 ,
3551 \\pub fn orMask(a: [1_000]u64, b: [1_000]u64) [1_000]u64 {
3552 \\ var c: [1_000]u64 = [1]u64{0xFFFF_FFFF_FFFF_FFFF} ** 1_000;
3553 \\ for (c[0_0..]) |_, i| {
3554 \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA;
3555 \\ }
3556 \\ return c;
3557 \\}
3558 \\
3559 );
3560}
35883561
3589//test "zig fmt: decimal float literals with underscore separators" {
3590// try testTransform(
3591// \\pub fn main() void {
3592// \\ const a:f64=(10.0e-0+(10.e+0))+10_00.00_00e-2+00_00.00_10e+4;
3593// \\ const b:f64=010.0--0_10.+0_1_0.0_0+1e2;
3594// \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3595// \\}
3596// ,
3597// \\pub fn main() void {
3598// \\ const a: f64 = (10.0e-0 + (10.e+0)) + 10_00.00_00e-2 + 00_00.00_10e+4;
3599// \\ const b: f64 = 010.0 - -0_10. + 0_1_0.0_0 + 1e2;
3600// \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3601// \\}
3602// \\
3603// );
3604//}
3562test "zig fmt: decimal float literals with underscore separators" {
3563 try testTransform(
3564 \\pub fn main() void {
3565 \\ const a:f64=(10.0e-0+(10.e+0))+10_00.00_00e-2+00_00.00_10e+4;
3566 \\ const b:f64=010.0--0_10.+0_1_0.0_0+1e2;
3567 \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3568 \\}
3569 ,
3570 \\pub fn main() void {
3571 \\ const a: f64 = (10.0e-0 + (10.e+0)) + 10_00.00_00e-2 + 00_00.00_10e+4;
3572 \\ const b: f64 = 010.0 - -0_10. + 0_1_0.0_0 + 1e2;
3573 \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3574 \\}
3575 \\
3576 );
3577}
36053578
3606//test "zig fmt: hexadeciaml float literals with underscore separators" {
3607// try testTransform(
3608// \\pub fn main() void {
3609// \\ const a: f64 = (0x10.0p-0+(0x10.p+0))+0x10_00.00_00p-8+0x00_00.00_10p+16;
3610// \\ const b: f64 = 0x0010.0--0x00_10.+0x10.00+0x1p4;
3611// \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3612// \\}
3613// ,
3614// \\pub fn main() void {
3615// \\ const a: f64 = (0x10.0p-0 + (0x10.p+0)) + 0x10_00.00_00p-8 + 0x00_00.00_10p+16;
3616// \\ const b: f64 = 0x0010.0 - -0x00_10. + 0x10.00 + 0x1p4;
3617// \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3618// \\}
3619// \\
3620// );
3621//}
3579test "zig fmt: hexadeciaml float literals with underscore separators" {
3580 try testTransform(
3581 \\pub fn main() void {
3582 \\ const a: f64 = (0x10.0p-0+(0x10.p+0))+0x10_00.00_00p-8+0x00_00.00_10p+16;
3583 \\ const b: f64 = 0x0010.0--0x00_10.+0x10.00+0x1p4;
3584 \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3585 \\}
3586 ,
3587 \\pub fn main() void {
3588 \\ const a: f64 = (0x10.0p-0 + (0x10.p+0)) + 0x10_00.00_00p-8 + 0x00_00.00_10p+16;
3589 \\ const b: f64 = 0x0010.0 - -0x00_10. + 0x10.00 + 0x1p4;
3590 \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
3591 \\}
3592 \\
3593 );
3594}
36223595
36233596//test "zig fmt: C var args" {
36243597// try testCanonical(
lib/std/zig/render.zig+64-102
......@@ -37,66 +37,56 @@ pub fn render(gpa: *mem.Allocator, tree: ast.Tree) Error![]u8 {
3737 return buffer.toOwnedSlice();
3838}
3939
40/// Assumes there are no tokens in between start and end.
41fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize, prefix: []const u8) Error!usize {
40/// Assumes that start is the first byte past the previous token and
41/// that end is the last byte before the next token.
42fn renderCommentsAndNewlines(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!bool {
4243 var index: usize = start;
43 var count: usize = 0;
44 while (true) {
45 const comment_start = index +
46 (mem.indexOf(u8, tree.source[index..end], "//") orelse return count);
44 while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| {
45 const comment_start = index + offset;
4746 const newline = comment_start +
4847 mem.indexOfScalar(u8, tree.source[comment_start..end], '\n').?;
4948 const untrimmed_comment = tree.source[comment_start..newline];
5049 const trimmed_comment = mem.trimRight(u8, untrimmed_comment, " \r\t");
51 if (count == 0) {
52 count += 1;
53 try ais.writer().writeAll(prefix);
54 } else {
55 // If another newline occurs between prev comment and this one
56 // we honor it, but not any additional ones.
57 if (mem.indexOfScalar(u8, tree.source[index..comment_start], '\n') != null) {
58 try ais.insertNewline();
59 }
50
51 // Leave up to one empty line before the comment
52 if (index == start and mem.containsAtLeast(u8, tree.source[index..comment_start], 2, "\n")) {
53 try ais.insertNewline();
54 try ais.insertNewline();
55 } else if (mem.indexOfScalar(u8, tree.source[index..comment_start], '\n') != null) {
56 // Respect the newline directly before the comment. This allows an
57 // empty line between comments
58 try ais.insertNewline();
59 } else if (index == start and start != 0) {
60 // If the comment is on the same line as the token before it,
61 // prefix it with a single space
62 try ais.writer().writeByte(' ');
6063 }
64
6165 try ais.writer().print("{s}\n", .{trimmed_comment});
6266 index = newline + 1;
6367 }
68
69 // Leave up to one empty line if present in the source
70 if (index > start) index -= 1;
71 if (end != tree.source.len and mem.containsAtLeast(u8, tree.source[index..end], 2, "\n")) {
72 try ais.insertNewline();
73 }
74
75 return index != start;
6476}
6577
6678fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void {
6779 // Render all the line comments at the beginning of the file.
6880 const src_start: usize = if (mem.startsWith(u8, tree.source, "\xEF\xBB\xBF")) 3 else 0;
6981 const comment_end_loc: usize = tree.tokens.items(.start)[0];
70 _ = try renderComments(ais, tree, src_start, comment_end_loc, "");
82 _ = try renderCommentsAndNewlines(ais, tree, src_start, comment_end_loc);
7183
7284 // Root is always index 0.
7385 const nodes_data = tree.nodes.items(.data);
7486 const root_decls = tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs];
7587
76 return renderAllMembers(ais, tree, root_decls);
77}
78
79fn renderAllMembers(ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void {
80 if (members.len == 0) return;
81
82 const first_member = members[0];
83 try renderMember(ais, tree, first_member, .Newline);
84
85 for (members[1..]) |member| {
86 try renderExtraNewline(ais, tree, member);
87 try renderMember(ais, tree, member, .Newline);
88 }
89}
90
91fn renderExtraNewline(ais: *Ais, tree: ast.Tree, node: ast.Node.Index) Error!void {
92 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));
93}
94
95fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, first_token: ast.TokenIndex) Error!void {
96 if (first_token == 0) return;
97 const token_starts = tree.tokens.items(.start);
98 if (tree.tokenLocation(token_starts[first_token - 1], first_token).line >= 2) {
99 return ais.insertNewline();
88 for (root_decls) |decl| {
89 try renderMember(ais, tree, decl, .Newline);
10090 }
10191}
10292
......@@ -499,9 +489,11 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
499489 },
500490
501491 .GroupedExpression => {
502 try renderToken(ais, tree, main_tokens[node], .None);
492 ais.pushIndentNextLine();
493 try renderToken(ais, tree, main_tokens[node], .None); // lparen
503494 try renderExpression(ais, tree, datas[node].lhs, .None);
504 return renderToken(ais, tree, datas[node].rhs, space);
495 ais.popIndent();
496 return renderToken(ais, tree, datas[node].rhs, space); // rparen
505497 },
506498
507499 .ContainerDecl,
......@@ -552,7 +544,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
552544 ais.pushIndent();
553545 var i = lbrace + 1;
554546 while (i < rbrace) : (i += 1) {
555 try renderExtraNewlineToken(ais, tree, i);
556547 switch (token_tags[i]) {
557548 .DocComment => try renderToken(ais, tree, i, .Newline),
558549 .Identifier => try renderToken(ais, tree, i, .Comma),
......@@ -635,11 +626,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
635626 try renderToken(ais, tree, rparen + 1, .None); // lbrace
636627 return renderToken(ais, tree, rparen + 2, space); // rbrace
637628 }
629 ais.pushIndentNextLine();
638630 try renderToken(ais, tree, rparen + 1, .Newline); // lbrace
639 ais.pushIndent();
640 try renderExpression(ais, tree, cases[0], .Comma);
641 for (cases[1..]) |case| {
642 try renderExtraNewline(ais, tree, case);
631 for (cases) |case| {
643632 try renderExpression(ais, tree, case, .Comma);
644633 }
645634 ais.popIndent();
......@@ -1469,9 +1458,7 @@ fn renderSwitchCase(
14691458 try renderExpression(ais, tree, switch_case.ast.values[0], .Space);
14701459 } else if (trailing_comma) {
14711460 // Render each value on a new line
1472 try renderExpression(ais, tree, switch_case.ast.values[0], .Comma);
1473 for (switch_case.ast.values[1..]) |value_expr| {
1474 try renderExtraNewline(ais, tree, value_expr);
1461 for (switch_case.ast.values) |value_expr| {
14751462 try renderExpression(ais, tree, value_expr, .Comma);
14761463 }
14771464 } else {
......@@ -1519,12 +1506,14 @@ fn renderBlock(
15191506 }
15201507
15211508 if (statements.len == 0) {
1509 ais.pushIndentNextLine();
15221510 try renderToken(ais, tree, lbrace, .None);
1511 ais.popIndent();
15231512 return renderToken(ais, tree, lbrace + 1, space); // rbrace
15241513 }
15251514
1515 ais.pushIndentNextLine();
15261516 try renderToken(ais, tree, lbrace, .Newline);
1527 ais.pushIndent();
15281517 for (statements) |stmt, i| {
15291518 switch (node_tags[stmt]) {
15301519 .GlobalVarDecl => try renderVarDecl(ais, tree, tree.globalVarDecl(stmt)),
......@@ -1533,9 +1522,6 @@ fn renderBlock(
15331522 .AlignedVarDecl => try renderVarDecl(ais, tree, tree.alignedVarDecl(stmt)),
15341523 else => try renderExpression(ais, tree, stmt, .Semicolon),
15351524 }
1536 if (i + 1 < statements.len) {
1537 try renderExtraNewline(ais, tree, statements[i + 1]);
1538 }
15391525 }
15401526 ais.popIndent();
15411527
......@@ -1566,18 +1552,14 @@ fn renderStructInit(
15661552 ais.pushIndent();
15671553 try renderToken(ais, tree, struct_init.ast.lbrace, .Newline);
15681554
1569 try renderToken(ais, tree, struct_init.ast.lbrace + 1, .None); // .
1570 try renderToken(ais, tree, struct_init.ast.lbrace + 2, .Space); // name
1571 try renderToken(ais, tree, struct_init.ast.lbrace + 3, .Space); // =
1572 try renderExpression(ais, tree, struct_init.ast.fields[0], .Comma);
1573
1574 for (struct_init.ast.fields[1..]) |field_init| {
1555 for (struct_init.ast.fields) |field_init| {
15751556 const init_token = tree.firstToken(field_init);
15761557 try renderToken(ais, tree, init_token - 3, .None); // .
15771558 try renderToken(ais, tree, init_token - 2, .Space); // name
15781559 try renderToken(ais, tree, init_token - 1, .Space); // =
1579 try renderExpressionNewlined(ais, tree, field_init, .Comma);
1560 try renderExpression(ais, tree, field_init, .Comma);
15801561 }
1562
15811563 ais.popIndent();
15821564 return renderToken(ais, tree, last_field_token + 2, space); // rbrace
15831565 } else {
......@@ -1620,9 +1602,8 @@ fn renderArrayInit(
16201602 ais.pushIndent();
16211603 try renderToken(ais, tree, array_init.ast.lbrace, .Newline);
16221604
1623 try renderExpression(ais, tree, array_init.ast.elements[0], .Comma);
1624 for (array_init.ast.elements[1..]) |elem| {
1625 try renderExpressionNewlined(ais, tree, elem, .Comma);
1605 for (array_init.ast.elements) |elem| {
1606 try renderExpression(ais, tree, elem, .Comma);
16261607 }
16271608
16281609 ais.popIndent();
......@@ -1693,7 +1674,7 @@ fn renderContainerDecl(
16931674 const last_member_token = tree.lastToken(last_member);
16941675 const rbrace = switch (token_tags[last_member_token + 1]) {
16951676 .DocComment => last_member_token + 2,
1696 .Comma => switch (token_tags[last_member_token + 2]) {
1677 .Comma, .Semicolon => switch (token_tags[last_member_token + 2]) {
16971678 .DocComment => last_member_token + 3,
16981679 .RBrace => last_member_token + 2,
16991680 else => unreachable,
......@@ -1719,7 +1700,9 @@ fn renderContainerDecl(
17191700 // One member per line.
17201701 ais.pushIndent();
17211702 try renderToken(ais, tree, lbrace, .Newline); // lbrace
1722 try renderAllMembers(ais, tree, container_decl.ast.members);
1703 for (container_decl.ast.members) |member| {
1704 try renderMember(ais, tree, member, .Newline);
1705 }
17231706 ais.popIndent();
17241707
17251708 return renderToken(ais, tree, rbrace, space); // rbrace
......@@ -1781,7 +1764,6 @@ fn renderAsm(
17811764
17821765 const comma = tree.firstToken(next_asm_output) - 1;
17831766 try renderToken(ais, tree, comma, .Newline); // ,
1784 try renderExtraNewlineToken(ais, tree, tree.firstToken(next_asm_output));
17851767 } else if (asm_node.inputs.len == 0 and asm_node.first_clobber == null) {
17861768 try renderAsmOutput(ais, tree, asm_output, .Newline);
17871769 ais.popIndent();
......@@ -1813,7 +1795,6 @@ fn renderAsm(
18131795
18141796 const first_token = tree.firstToken(next_asm_input);
18151797 try renderToken(ais, tree, first_token - 1, .Newline); // ,
1816 try renderExtraNewlineToken(ais, tree, first_token);
18171798 } else if (asm_node.first_clobber == null) {
18181799 try renderAsmInput(ais, tree, asm_input, .Newline);
18191800 ais.popIndent();
......@@ -1894,8 +1875,6 @@ fn renderCall(
18941875 try renderToken(ais, tree, comma, Space.Newline); // ,
18951876
18961877 if (is_multiline_string) ais.pushIndent();
1897
1898 try renderExtraNewline(ais, tree, params[i + 1]);
18991878 } else {
19001879 try renderExpression(ais, tree, param_node, Space.Comma);
19011880 }
......@@ -1929,22 +1908,6 @@ fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space:
19291908 }
19301909}
19311910
1932/// Render an expression, but first insert an extra newline if the previous token is 2 or
1933/// more lines away.
1934fn renderExpressionNewlined(
1935 ais: *Ais,
1936 tree: ast.Tree,
1937 node: ast.Node.Index,
1938 space: Space,
1939) Error!void {
1940 const token_starts = tree.tokens.items(.start);
1941 const first_token = tree.firstToken(node);
1942 if (tree.tokenLocation(token_starts[first_token - 1], first_token).line >= 2) {
1943 try ais.insertNewline();
1944 }
1945 return renderExpression(ais, tree, node, space);
1946}
1947
19481911fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Space) Error!void {
19491912 const token_tags = tree.tokens.items(.tag);
19501913 const maybe_comma = token + 1;
......@@ -1996,40 +1959,39 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
19961959
19971960 switch (space) {
19981961 .NoComment => {},
1999 .None => {},
1962 .None => _ = try renderCommentsAndNewlines(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]),
20001963 .Comma => {
2001 const count = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ", ");
2002 if (count == 0 and token_tags[token_index + 1] == .Comma) {
2003 return renderToken(ais, tree, token_index + 1, Space.Newline);
2004 }
2005 try ais.writer().writeAll(",");
2006
2007 if (token_tags[token_index + 2] != .MultilineStringLiteralLine) {
2008 try ais.insertNewline();
1964 const comment = try renderCommentsAndNewlines(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]);
1965 if (token_tags[token_index + 1] == .Comma) {
1966 return renderToken(ais, tree, token_index + 1, .Newline);
1967 } else if (!comment) {
1968 return ais.insertNewline();
20091969 }
20101970 },
20111971 .CommaSpace => {
2012 _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], "");
1972 const comment = try renderCommentsAndNewlines(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]);
20131973 if (token_tags[token_index + 1] == .Comma) {
20141974 return renderToken(ais, tree, token_index + 1, .Space);
2015 } else {
1975 } else if (!comment) {
20161976 return ais.writer().writeByte(' ');
20171977 }
20181978 },
20191979 .Semicolon => {
2020 _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], "");
1980 const comment = try renderCommentsAndNewlines(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]);
20211981 if (token_tags[token_index + 1] == .Semicolon) {
20221982 return renderToken(ais, tree, token_index + 1, .Newline);
2023 } else {
1983 } else if (!comment) {
20241984 return ais.insertNewline();
20251985 }
20261986 },
20271987 .Space => {
2028 _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], "");
2029 return ais.writer().writeByte(' ');
1988 const comment = try renderCommentsAndNewlines(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]);
1989 if (!comment) {
1990 return ais.writer().writeByte(' ');
1991 }
20301992 },
20311993 .Newline => {
2032 if (token_tags[token_index + 1] != .MultilineStringLiteralLine) {
1994 if (!try renderCommentsAndNewlines(ais, tree, token_start + lexeme.len, token_starts[token_index + 1])) {
20331995 try ais.insertNewline();
20341996 }
20351997 },