zig fmt: implement multiline string literals
This commit is contained in:
committed by
Andrew Kelley
parent
75ba8d8db6
commit
24798b84ad
@@ -50,35 +50,35 @@ test "zig fmt: respect line breaks after var declarations" {
|
||||
);
|
||||
}
|
||||
|
||||
//test "zig fmt: multiline string mixed with comments" {
|
||||
// try testCanonical(
|
||||
// \\const s1 =
|
||||
// \\ //\\one
|
||||
// \\ \\two)
|
||||
// \\ \\three
|
||||
// \\;
|
||||
// \\const s2 =
|
||||
// \\ \\one
|
||||
// \\ \\two)
|
||||
// \\ //\\three
|
||||
// \\;
|
||||
// \\const s3 =
|
||||
// \\ \\one
|
||||
// \\ //\\two)
|
||||
// \\ \\three
|
||||
// \\;
|
||||
// \\const s4 =
|
||||
// \\ \\one
|
||||
// \\ //\\two
|
||||
// \\ \\three
|
||||
// \\ //\\four
|
||||
// \\ \\five
|
||||
// \\;
|
||||
// \\const a =
|
||||
// \\ 1;
|
||||
// \\
|
||||
// );
|
||||
//}
|
||||
test "zig fmt: multiline string mixed with comments" {
|
||||
try testCanonical(
|
||||
\\const s1 =
|
||||
\\ //\\one
|
||||
\\ \\two)
|
||||
\\ \\three
|
||||
\\;
|
||||
\\const s2 =
|
||||
\\ \\one
|
||||
\\ \\two)
|
||||
\\ //\\three
|
||||
\\;
|
||||
\\const s3 =
|
||||
\\ \\one
|
||||
\\ //\\two)
|
||||
\\ \\three
|
||||
\\;
|
||||
\\const s4 =
|
||||
\\ \\one
|
||||
\\ //\\two
|
||||
\\ \\three
|
||||
\\ //\\four
|
||||
\\ \\five
|
||||
\\;
|
||||
\\const a =
|
||||
\\ 1;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: empty file" {
|
||||
try testCanonical(
|
||||
@@ -974,25 +974,25 @@ test "zig fmt: character literal larger than u8" {
|
||||
);
|
||||
}
|
||||
|
||||
//test "zig fmt: infix operator and then multiline string literal" {
|
||||
// try testCanonical(
|
||||
// \\const x = "" ++
|
||||
// \\ \\ hi
|
||||
// \\;
|
||||
// \\
|
||||
// );
|
||||
//}
|
||||
//
|
||||
//test "zig fmt: infix operator and then multiline string literal" {
|
||||
// try testCanonical(
|
||||
// \\const x = "" ++
|
||||
// \\ \\ hi0
|
||||
// \\ \\ hi1
|
||||
// \\ \\ hi2
|
||||
// \\;
|
||||
// \\
|
||||
// );
|
||||
//}
|
||||
test "zig fmt: infix operator and then multiline string literal" {
|
||||
try testCanonical(
|
||||
\\const x = "" ++
|
||||
\\ \\ hi
|
||||
\\;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: infix operator and then multiline string literal" {
|
||||
try testCanonical(
|
||||
\\const x = "" ++
|
||||
\\ \\ hi0
|
||||
\\ \\ hi1
|
||||
\\ \\ hi2
|
||||
\\;
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: C pointers" {
|
||||
try testCanonical(
|
||||
@@ -1725,35 +1725,35 @@ test "zig fmt: struct literal no trailing comma" {
|
||||
// \\
|
||||
// );
|
||||
//}
|
||||
//
|
||||
//test "zig fmt: multiline string with backslash at end of line" {
|
||||
// try testCanonical(
|
||||
// \\comptime {
|
||||
// \\ err(
|
||||
// \\ \\\
|
||||
// \\ );
|
||||
// \\}
|
||||
// \\
|
||||
// );
|
||||
//}
|
||||
//
|
||||
//test "zig fmt: multiline string parameter in fn call with trailing comma" {
|
||||
// try testCanonical(
|
||||
// \\fn foo() void {
|
||||
// \\ try stdout.print(
|
||||
// \\ \\ZIG_CMAKE_BINARY_DIR {}
|
||||
// \\ \\ZIG_C_HEADER_FILES {}
|
||||
// \\ \\ZIG_DIA_GUIDS_LIB {}
|
||||
// \\ \\
|
||||
// \\ ,
|
||||
// \\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),
|
||||
// \\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),
|
||||
// \\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
|
||||
// \\ );
|
||||
// \\}
|
||||
// \\
|
||||
// );
|
||||
//}
|
||||
|
||||
test "zig fmt: multiline string with backslash at end of line" {
|
||||
try testCanonical(
|
||||
\\comptime {
|
||||
\\ err(
|
||||
\\ \\\
|
||||
\\ );
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: multiline string parameter in fn call with trailing comma" {
|
||||
try testCanonical(
|
||||
\\fn foo() void {
|
||||
\\ try stdout.print(
|
||||
\\ \\ZIG_CMAKE_BINARY_DIR {}
|
||||
\\ \\ZIG_C_HEADER_FILES {}
|
||||
\\ \\ZIG_DIA_GUIDS_LIB {}
|
||||
\\ \\
|
||||
\\ ,
|
||||
\\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),
|
||||
\\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),
|
||||
\\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
|
||||
\\ );
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: trailing comma on fn call" {
|
||||
try testCanonical(
|
||||
|
||||
@@ -146,7 +146,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
|
||||
.identifier,
|
||||
.integer_literal,
|
||||
.float_literal,
|
||||
.string_literal,
|
||||
.char_literal,
|
||||
.true_literal,
|
||||
.false_literal,
|
||||
@@ -156,6 +155,29 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
|
||||
.anyframe_literal,
|
||||
=> return renderToken(ais, tree, main_tokens[node], space),
|
||||
|
||||
.string_literal => switch (token_tags[main_tokens[node]]) {
|
||||
.string_literal => try renderToken(ais, tree, main_tokens[node], space),
|
||||
|
||||
.multiline_string_literal_line => {
|
||||
var locked_indents = ais.lockOneShotIndent();
|
||||
try ais.maybeInsertNewline();
|
||||
|
||||
var i = datas[node].lhs;
|
||||
while (i <= datas[node].rhs) : (i += 1) try renderToken(ais, tree, i, .newline);
|
||||
|
||||
while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent();
|
||||
|
||||
switch (space) {
|
||||
.none => {},
|
||||
.semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),
|
||||
.comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),
|
||||
.comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
|
||||
.error_value => {
|
||||
try renderToken(ais, tree, main_tokens[node], .none);
|
||||
try renderToken(ais, tree, main_tokens[node] + 1, .none);
|
||||
@@ -1821,7 +1843,7 @@ fn renderCall(
|
||||
const last_param = params[params.len - 1];
|
||||
const after_last_param_tok = tree.lastToken(last_param) + 1;
|
||||
if (token_tags[after_last_param_tok] == .comma) {
|
||||
ais.pushIndent();
|
||||
ais.pushIndentNextLine();
|
||||
try renderToken(ais, tree, lparen, Space.newline); // (
|
||||
for (params) |param_node, i| {
|
||||
if (i + 1 < params.len) {
|
||||
@@ -1846,6 +1868,7 @@ fn renderCall(
|
||||
return renderToken(ais, tree, after_last_param_tok + 1, space); // )
|
||||
}
|
||||
|
||||
ais.pushIndentNextLine();
|
||||
try renderToken(ais, tree, lparen, Space.none); // (
|
||||
|
||||
for (params) |param_node, i| {
|
||||
@@ -1856,6 +1879,8 @@ fn renderCall(
|
||||
try renderToken(ais, tree, comma, Space.space);
|
||||
}
|
||||
}
|
||||
|
||||
ais.popIndent();
|
||||
return renderToken(ais, tree, after_last_param_tok, space); // )
|
||||
}
|
||||
|
||||
@@ -1907,7 +1932,8 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
|
||||
const token_start = token_starts[token_index];
|
||||
const lexeme = tree.tokenSlice(token_index);
|
||||
const lexeme = tokenSliceForRender(tree, token_index);
|
||||
|
||||
try ais.writer().writeAll(lexeme);
|
||||
|
||||
if (space == .no_comment) return;
|
||||
@@ -1991,7 +2017,7 @@ fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenInde
|
||||
const prev_token_end = if (token_index == 0)
|
||||
0
|
||||
else
|
||||
token_starts[token_index - 1] + tree.tokenSlice(token_index - 1).len;
|
||||
token_starts[token_index - 1] + tokenSliceForRender(tree, token_index - 1).len;
|
||||
|
||||
// If there is a comment present, it will handle the empty line
|
||||
if (mem.indexOf(u8, tree.source[prev_token_end..token_start], "//") != null) return;
|
||||
@@ -2034,6 +2060,15 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error
|
||||
}
|
||||
}
|
||||
|
||||
fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {
|
||||
var ret = tree.tokenSlice(token_index);
|
||||
if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) {
|
||||
assert(ret[ret.len - 1] == '\n');
|
||||
ret.len -= 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn nodeIsBlock(tag: ast.Node.Tag) bool {
|
||||
return switch (tag) {
|
||||
.block,
|
||||
|
||||
Reference in New Issue
Block a user