zig fmt: fix render of pointers with ** tokens

This commit is contained in:
Isaac Freund 2021-02-10 16:00:54 +01:00 committed by Andrew Kelley
parent a524e57090
commit 8c4f3e5a31
3 changed files with 83 additions and 48 deletions

View File

@ -407,7 +407,9 @@ pub const Tree = struct {
=> {
const main_token = main_tokens[n];
return switch (token_tags[main_token]) {
.Asterisk => switch (token_tags[main_token - 1]) {
.Asterisk,
.AsteriskAsterisk,
=> switch (token_tags[main_token - 1]) {
.LBracket => main_token - 1,
else => main_token,
},
@ -1625,7 +1627,9 @@ pub const Tree = struct {
// literals in some places here
const Kind = full.PtrType.Kind;
const kind: Kind = switch (token_tags[info.main_token]) {
.Asterisk => switch (token_tags[info.main_token + 1]) {
.Asterisk,
.AsteriskAsterisk,
=> switch (token_tags[info.main_token + 1]) {
.RBracket => .many,
.Colon => .sentinel,
.Identifier => if (token_tags[info.main_token - 1] == .LBracket) Kind.c else .one,
@ -2393,18 +2397,26 @@ pub const Node = struct {
/// `[*]align(lhs) rhs`. lhs can be omitted.
/// `*align(lhs) rhs`. lhs can be omitted.
/// `[]rhs`.
/// main_token is the asterisk if a pointer or the lbrace if a slice
/// main_token is the asterisk if a pointer or the lbracket if a slice
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
PtrTypeAligned,
/// `[*:lhs]rhs`. lhs can be omitted.
/// `*rhs`.
/// `[:lhs]rhs`.
/// main_token is the asterisk if a pointer or the lbrace if a slice
/// main_token is the asterisk if a pointer or the lbracket if a slice
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
PtrTypeSentinel,
/// lhs is index into PtrType. rhs is the element type expression.
/// main_token is the asterisk if a pointer or the lbrace if a slice
/// main_token is the asterisk if a pointer or the lbracket if a slice
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
PtrType,
/// lhs is index into PtrTypeBitRange. rhs is the element type expression.
/// main_token is the asterisk if a pointer or the lbrace if a slice
/// main_token is the asterisk if a pointer or the lbracket if a slice
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
PtrTypeBitRange,
/// `lhs[rhs..]`
/// main_token is the lbracket.

View File

@ -2318,27 +2318,27 @@ test "zig fmt: alignment" {
);
}
//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: 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(
@ -2356,27 +2356,40 @@ test "zig fmt: function attributes" {
);
}
//test "zig fmt: pointer attributes" {
// try testCanonical(
// \\extern fn f1(s: *align(*u8) u8) c_int;
// \\extern fn f2(s: **align(1) *const *volatile u8) c_int;
// \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int;
// \\extern fn f4(s: *align(1) const volatile u8) c_int;
// \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int;
// \\
// );
//}
//
//test "zig fmt: slice attributes" {
// try testCanonical(
// \\extern fn f1(s: *align(*u8) u8) c_int;
// \\extern fn f2(s: **align(1) *const *volatile u8) c_int;
// \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int;
// \\extern fn f4(s: *align(1) const volatile u8) c_int;
// \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int;
// \\
// );
//}
test "zig fmt: nested pointers with ** tokens" {
try testCanonical(
\\const x: *u32 = undefined;
\\const x: **u32 = undefined;
\\const x: ***u32 = undefined;
\\const x: ****u32 = undefined;
\\const x: *****u32 = undefined;
\\const x: ******u32 = undefined;
\\const x: *******u32 = undefined;
\\
);
}
test "zig fmt: pointer attributes" {
try testCanonical(
\\extern fn f1(s: *align(*u8) u8) c_int;
\\extern fn f2(s: **align(1) *const *volatile u8) c_int;
\\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int;
\\extern fn f4(s: *align(1) const volatile u8) c_int;
\\extern fn f5(s: [*:0]align(1) const volatile u8) c_int;
\\
);
}
test "zig fmt: slice attributes" {
try testCanonical(
\\extern fn f1(s: []align(*u8) u8) c_int;
\\extern fn f2(s: []align(1) []const []volatile u8) c_int;
\\extern fn f3(s: []align(1) const [:0]align(1) volatile []const volatile u8) c_int;
\\extern fn f4(s: []align(1) const volatile u8) c_int;
\\extern fn f5(s: [:0]align(1) const volatile u8) c_int;
\\
);
}
test "zig fmt: test declaration" {
try testCanonical(

View File

@ -699,6 +699,16 @@ fn renderPtrType(
) Error!void {
switch (ptr_type.kind) {
.one => {
// Since ** tokens exist and the same token is shared by two
// nested pointer types, we check to see if we are the parent
// in such a relationship. If so, skip rendering anything for
// this pointer type and rely on the child to render our asterisk
// as well when it renders the ** token.
if (tree.tokens.items(.tag)[ptr_type.ast.main_token] == .AsteriskAsterisk and
ptr_type.ast.main_token == tree.nodes.items(.main_token)[ptr_type.ast.child_type])
{
return renderExpression(ais, tree, ptr_type.ast.child_type, space);
}
try renderToken(ais, tree, ptr_type.ast.main_token, .None); // asterisk
},
.many => {