diff --git a/lib/std/zig/Ast/Render.zig b/lib/std/zig/Ast/Render.zig index 8f5b2e2c276f5b8680fb56173154bcbdbf8966e6..2c430ca716fcaace9e76ad67d80348ff3a88fb66 100644 --- a/lib/std/zig/Ast/Render.zig +++ b/lib/std/zig/Ast/Render.zig @@ -1652,7 +1652,17 @@ fn renderBuiltinCall( const tree = r.tree; const ais = r.ais; - try renderToken(r, builtin_token, .none); // @name + // remove before 0.18.0 is released + const builtin_token_slice = tree.tokenSlice(builtin_token); // @name + const lexeme: []const u8, const have_int_cast: bool = lexeme: { + if (mem.eql(u8, builtin_token_slice, "@intFromEnum")) + break :lexeme .{ "@backingInt", false }; + if (mem.eql(u8, builtin_token_slice, "@enumFromInt")) + break :lexeme .{ "@fromBackingInt(@intCast", true }; + break :lexeme .{ builtin_token_slice, false }; + }; + try ais.writeAll(lexeme); + try renderSpace(r, builtin_token, builtin_token_slice.len, .none); if (r.fixups.rebase_imported_paths) |prefix| { const slice = tree.tokenSlice(builtin_token); @@ -1675,7 +1685,14 @@ fn renderBuiltinCall( } } - return renderParamList(r, builtin_token + 1, params, space); + try renderParamList(r, builtin_token + 1, params, .skip); // space is rendered below + if (have_int_cast) try ais.writeAll(")"); + const rparen: Ast.TokenIndex = rparen: { + if (params.len == 0) break :rparen builtin_token + 1 + 1; + const after_last_param_tok = tree.lastToken(params[params.len - 1]) + 1; + break :rparen after_last_param_tok + @intFromBool(tree.tokenTag(after_last_param_tok) == .comma); + }; + return renderSpace(r, rparen, tokenSliceForRender(tree, rparen).len, space); } fn fnProtoRparen(tree: Ast, fn_proto: Ast.full.FnProto, maybe_bang: Ast.TokenIndex) Ast.TokenIndex { diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index c471a2d20f1c5d9d8a7d75ce9e2bde4502418e43..7e149d14fdee9105ac1b17c9e70f46197c81f638 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -6938,6 +6938,66 @@ test "zig fmt: inner over-indented if expressions becoming multiline" { ); } +test "zig fmt: canonicalize @intFromEnum(x) to @backingInt(x)" { + try testTransform( + \\const a = @intFromEnum(x); + \\ + \\const b = @intFromEnum( + \\ x, + \\); + \\ + \\const c = @intFromEnum(x); // comment preserved + \\ + \\const d = @intFromEnum( // comment 1 preserved + \\ x, // comment 2 preserved + \\); // comment 3 preserved + \\ + , + \\const a = @backingInt(x); + \\ + \\const b = @backingInt( + \\ x, + \\); + \\ + \\const c = @backingInt(x); // comment preserved + \\ + \\const d = @backingInt( // comment 1 preserved + \\ x, // comment 2 preserved + \\); // comment 3 preserved + \\ + ); +} + +test "zig fmt: canonicalize @enumFromInt(x) to @fromBackingInt(@intCast(x))" { + try testTransform( + \\const a: E = @enumFromInt(x); + \\ + \\const b: E = @enumFromInt( + \\ x, + \\); + \\ + \\const c: E = @enumFromInt(x); // comment preserved + \\ + \\const d: E = @enumFromInt( // comment 1 preserved + \\ x, // comment 2 preserved + \\); // comment 3 preserved + \\ + , + \\const a: E = @fromBackingInt(@intCast(x)); + \\ + \\const b: E = @fromBackingInt(@intCast( + \\ x, + \\)); + \\ + \\const c: E = @fromBackingInt(@intCast(x)); // comment preserved + \\ + \\const d: E = @fromBackingInt(@intCast( // comment 1 preserved + \\ x, // comment 2 preserved + \\)); // comment 3 preserved + \\ + ); +} + test "recovery: top level" { try testError( \\test "" {inline}