zig fmt: support anon struct and anon list init syntax
parent
725b6ee634
commit
d4e6a6d5e2
|
@ -1648,10 +1648,15 @@ pub const Node = struct {
|
|||
|
||||
pub const SuffixOp = struct {
|
||||
base: Node,
|
||||
lhs: *Node,
|
||||
lhs: Lhs,
|
||||
op: Op,
|
||||
rtoken: TokenIndex,
|
||||
|
||||
pub const Lhs = union(enum) {
|
||||
node: *Node,
|
||||
dot: TokenIndex,
|
||||
};
|
||||
|
||||
pub const Op = union(enum) {
|
||||
Call: Call,
|
||||
ArrayAccess: *Node,
|
||||
|
@ -1679,8 +1684,13 @@ pub const Node = struct {
|
|||
pub fn iterate(self: *SuffixOp, index: usize) ?*Node {
|
||||
var i = index;
|
||||
|
||||
if (i < 1) return self.lhs;
|
||||
i -= 1;
|
||||
switch (self.lhs) {
|
||||
.node => |node| {
|
||||
if (i == 0) return node;
|
||||
i -= 1;
|
||||
},
|
||||
.dot => {},
|
||||
}
|
||||
|
||||
switch (self.op) {
|
||||
.Call => |*call_info| {
|
||||
|
@ -1721,7 +1731,10 @@ pub const Node = struct {
|
|||
.Call => |*call_info| if (call_info.async_token) |async_token| return async_token,
|
||||
else => {},
|
||||
}
|
||||
return self.lhs.firstToken();
|
||||
switch (self.lhs) {
|
||||
.node => |node| return node.firstToken(),
|
||||
.dot => |dot| return dot,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lastToken(self: *const SuffixOp) TokenIndex {
|
||||
|
|
|
@ -1026,16 +1026,16 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
/// CurlySuffixExpr <- TypeExpr InitList?
|
||||
fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
|
||||
const init_list = (try parseInitList(arena, it, tree)) orelse return type_expr;
|
||||
init_list.cast(Node.SuffixOp).?.lhs = type_expr;
|
||||
return init_list;
|
||||
const suffix_op = (try parseInitList(arena, it, tree)) orelse return type_expr;
|
||||
suffix_op.lhs.node = type_expr;
|
||||
return &suffix_op.base;
|
||||
}
|
||||
|
||||
/// InitList
|
||||
/// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
|
||||
/// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
|
||||
/// / LBRACE RBRACE
|
||||
fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.SuffixOp {
|
||||
const lbrace = eatToken(it, .LBrace) orelse return null;
|
||||
var init_list = Node.SuffixOp.Op.InitList.init(arena);
|
||||
|
||||
|
@ -1064,11 +1064,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
const node = try arena.create(Node.SuffixOp);
|
||||
node.* = Node.SuffixOp{
|
||||
.base = Node{ .id = .SuffixOp },
|
||||
.lhs = undefined, // set by caller
|
||||
.lhs = .{.node = undefined}, // set by caller
|
||||
.op = op,
|
||||
.rtoken = try expectToken(it, tree, .RBrace),
|
||||
};
|
||||
return &node.base;
|
||||
return node;
|
||||
}
|
||||
|
||||
/// TypeExpr <- PrefixTypeOp* ErrorUnionExpr
|
||||
|
@ -1117,7 +1117,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
|
||||
while (try parseSuffixOp(arena, it, tree)) |node| {
|
||||
switch (node.id) {
|
||||
.SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
|
||||
.SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
|
||||
.InfixOp => node.cast(Node.InfixOp).?.lhs = res,
|
||||
else => unreachable,
|
||||
}
|
||||
|
@ -1133,7 +1133,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
const node = try arena.create(Node.SuffixOp);
|
||||
node.* = Node.SuffixOp{
|
||||
.base = Node{ .id = .SuffixOp },
|
||||
.lhs = res,
|
||||
.lhs = .{.node = res},
|
||||
.op = Node.SuffixOp.Op{
|
||||
.Call = Node.SuffixOp.Op.Call{
|
||||
.params = params.list,
|
||||
|
@ -1150,7 +1150,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
while (true) {
|
||||
if (try parseSuffixOp(arena, it, tree)) |node| {
|
||||
switch (node.id) {
|
||||
.SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
|
||||
.SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
|
||||
.InfixOp => node.cast(Node.InfixOp).?.lhs = res,
|
||||
else => unreachable,
|
||||
}
|
||||
|
@ -1161,7 +1161,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
const call = try arena.create(Node.SuffixOp);
|
||||
call.* = Node.SuffixOp{
|
||||
.base = Node{ .id = .SuffixOp },
|
||||
.lhs = res,
|
||||
.lhs = .{.node = res},
|
||||
.op = Node.SuffixOp.Op{
|
||||
.Call = Node.SuffixOp.Op.Call{
|
||||
.params = params.list,
|
||||
|
@ -1215,7 +1215,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
|
|||
return &node.base;
|
||||
}
|
||||
if (try parseContainerDecl(arena, it, tree)) |node| return node;
|
||||
if (try parseEnumLiteral(arena, it, tree)) |node| return node;
|
||||
if (try parseAnonLiteral(arena, it, tree)) |node| return node;
|
||||
if (try parseErrorSetDecl(arena, it, tree)) |node| return node;
|
||||
if (try parseFloatLiteral(arena, it, tree)) |node| return node;
|
||||
if (try parseFnProto(arena, it, tree)) |node| return node;
|
||||
|
@ -1494,16 +1494,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||
}
|
||||
|
||||
/// DOT IDENTIFIER
|
||||
fn parseEnumLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
fn parseAnonLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
const dot = eatToken(it, .Period) orelse return null;
|
||||
const name = try expectToken(it, tree, .Identifier);
|
||||
const node = try arena.create(Node.EnumLiteral);
|
||||
node.* = Node.EnumLiteral{
|
||||
.base = Node{ .id = .EnumLiteral },
|
||||
.dot = dot,
|
||||
.name = name,
|
||||
};
|
||||
return &node.base;
|
||||
|
||||
// anon enum literal
|
||||
if (eatToken(it, .Identifier)) |name| {
|
||||
const node = try arena.create(Node.EnumLiteral);
|
||||
node.* = Node.EnumLiteral{
|
||||
.base = Node{ .id = .EnumLiteral },
|
||||
.dot = dot,
|
||||
.name = name,
|
||||
};
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
// anon container literal
|
||||
if (try parseInitList(arena, it, tree)) |node| {
|
||||
node.lhs = .{.dot = dot};
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
putBackToken(it, dot);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// AsmOutput <- COLON AsmOutputList AsmInput?
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
test "zig fmt: anon struct literal syntax" {
|
||||
try testCanonical(
|
||||
\\const x = .{
|
||||
\\ .a = b,
|
||||
\\ .c = d,
|
||||
\\};
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: anon list literal syntax" {
|
||||
try testCanonical(
|
||||
\\const x = .{ a, b, c };
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: async function" {
|
||||
try testCanonical(
|
||||
\\pub const Server = struct {
|
||||
|
|
|
@ -538,9 +538,9 @@ fn renderExpression(
|
|||
try renderToken(tree, stream, async_token, indent, start_col, Space.Space);
|
||||
}
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
||||
|
||||
const lparen = tree.nextToken(suffix_op.lhs.lastToken());
|
||||
const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());
|
||||
|
||||
if (call_info.params.len == 0) {
|
||||
try renderToken(tree, stream, lparen, indent, start_col, Space.None);
|
||||
|
@ -598,7 +598,7 @@ fn renderExpression(
|
|||
const lbracket = tree.prevToken(index_expr.firstToken());
|
||||
const rbracket = tree.nextToken(index_expr.lastToken());
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
||||
try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
|
||||
|
||||
const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment;
|
||||
|
@ -616,18 +616,18 @@ fn renderExpression(
|
|||
},
|
||||
|
||||
ast.Node.SuffixOp.Op.Deref => {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .*
|
||||
},
|
||||
|
||||
ast.Node.SuffixOp.Op.UnwrapOptional => {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
||||
try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ?
|
||||
},
|
||||
|
||||
@TagType(ast.Node.SuffixOp.Op).Slice => |range| {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
|
||||
|
||||
const lbracket = tree.prevToken(range.start.firstToken());
|
||||
const dotdot = tree.nextToken(range.start.lastToken());
|
||||
|
@ -647,10 +647,16 @@ fn renderExpression(
|
|||
},
|
||||
|
||||
ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
|
||||
const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
|
||||
const lbrace = switch (suffix_op.lhs) {
|
||||
.dot => |dot| tree.nextToken(dot),
|
||||
.node => |node| tree.nextToken(node.lastToken()),
|
||||
};
|
||||
|
||||
if (field_inits.len == 0) {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
|
||||
}
|
||||
try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
}
|
||||
|
@ -691,7 +697,10 @@ fn renderExpression(
|
|||
break :blk;
|
||||
}
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
|
||||
}
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
|
@ -699,7 +708,10 @@ fn renderExpression(
|
|||
|
||||
if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {
|
||||
// render all on one line, no trailing comma
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
|
||||
}
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
|
||||
|
||||
var it = field_inits.iterator(0);
|
||||
|
@ -719,7 +731,10 @@ fn renderExpression(
|
|||
|
||||
const new_indent = indent + indent_delta;
|
||||
|
||||
try renderExpression(allocator, stream, tree, new_indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, new_indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.None),
|
||||
}
|
||||
try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
|
||||
|
||||
var it = field_inits.iterator(0);
|
||||
|
@ -743,23 +758,35 @@ fn renderExpression(
|
|||
},
|
||||
|
||||
ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
|
||||
const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
|
||||
const lbrace = switch (suffix_op.lhs) {
|
||||
.dot => |dot| tree.nextToken(dot),
|
||||
.node => |node| tree.nextToken(node.lastToken()),
|
||||
};
|
||||
|
||||
if (exprs.len == 0) {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
|
||||
}
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
}
|
||||
if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) {
|
||||
const expr = exprs.at(0).*;
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
|
||||
}
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
}
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
switch (suffix_op.lhs) {
|
||||
.dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
|
||||
.node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
|
||||
}
|
||||
|
||||
// scan to find row size
|
||||
const maybe_row_size: ?usize = blk: {
|
||||
|
|
Loading…
Reference in New Issue