zig fmt support for slice sentinel syntax
This commit is contained in:
@@ -1701,6 +1701,7 @@ pub const Node = struct {
|
||||
pub const Slice = struct {
|
||||
start: *Node,
|
||||
end: ?*Node,
|
||||
sentinel: ?*Node,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1732,6 +1733,10 @@ pub const Node = struct {
|
||||
if (i < 1) return end;
|
||||
i -= 1;
|
||||
}
|
||||
if (range.sentinel) |sentinel| {
|
||||
if (i < 1) return sentinel;
|
||||
i -= 1;
|
||||
}
|
||||
},
|
||||
.ArrayInitializer => |*exprs| {
|
||||
if (i < exprs.len) return exprs.at(i).*;
|
||||
|
||||
@@ -2331,7 +2331,7 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
|
||||
}
|
||||
|
||||
/// SuffixOp
|
||||
/// <- LBRACKET Expr (DOT2 Expr?)? RBRACKET
|
||||
/// <- LBRACKET Expr (DOT2 (Expr (COLON Expr)?)?)? RBRACKET
|
||||
/// / DOT IDENTIFIER
|
||||
/// / DOTASTERISK
|
||||
/// / DOTQUESTIONMARK
|
||||
@@ -2349,11 +2349,16 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
|
||||
if (eatToken(it, .Ellipsis2) != null) {
|
||||
const end_expr = try parseExpr(arena, it, tree);
|
||||
const sentinel: ?*ast.Node = if (eatToken(it, .Colon) != null)
|
||||
try parseExpr(arena, it, tree)
|
||||
else
|
||||
null;
|
||||
break :blk OpAndToken{
|
||||
.op = Op{
|
||||
.Slice = Op.Slice{
|
||||
.start = index_expr,
|
||||
.end = end_expr,
|
||||
.sentinel = sentinel,
|
||||
},
|
||||
},
|
||||
.token = try expectToken(it, tree, .RBracket),
|
||||
|
||||
@@ -419,10 +419,13 @@ test "zig fmt: pointer of unknown length" {
|
||||
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];
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
@@ -689,7 +689,13 @@ fn renderExpression(
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, range.start, after_start_space);
|
||||
try renderToken(tree, stream, dotdot, indent, start_col, after_op_space); // ..
|
||||
if (range.end) |end| {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, end, Space.None);
|
||||
const after_end_space = if (range.sentinel != null) Space.Space else Space.None;
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, end, after_end_space);
|
||||
}
|
||||
if (range.sentinel) |sentinel| {
|
||||
const colon = tree.prevToken(sentinel.firstToken());
|
||||
try renderToken(tree, stream, colon, indent, start_col, Space.None); // :
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, sentinel, Space.None);
|
||||
}
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ]
|
||||
},
|
||||
|
||||
@@ -78,3 +78,22 @@ test "access len index of sentinel-terminated slice" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "obtaining a null terminated slice" {
|
||||
// here we have a normal array
|
||||
var buf: [50]u8 = undefined;
|
||||
|
||||
buf[0] = 'a';
|
||||
buf[1] = 'b';
|
||||
buf[2] = 'c';
|
||||
buf[3] = 0;
|
||||
|
||||
// now we obtain a null terminated slice:
|
||||
const ptr = buf[0..3 :0];
|
||||
|
||||
var runtime_len: usize = 3;
|
||||
const ptr2 = buf[0..runtime_len :0];
|
||||
// ptr2 is a null-terminated slice
|
||||
comptime expect(@TypeOf(ptr2) == [:0]u8);
|
||||
comptime expect(@TypeOf(ptr2[0..2]) == []u8);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user