Fuzzer fixes (#940)
* better handling of container_decl_arg_trailing * ignore semantic token when moving backwards * use custom ast functions instead of from std
This commit is contained in:
parent
fe54fb7cfa
commit
6019eff13e
27
src/ast.zig
27
src/ast.zig
@ -254,29 +254,29 @@ pub fn forFull(tree: Ast, node: Node.Index) full.While {
|
|||||||
|
|
||||||
pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType {
|
pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType {
|
||||||
return switch (tree.nodes.items(.tag)[node]) {
|
return switch (tree.nodes.items(.tag)[node]) {
|
||||||
.ptr_type_aligned => tree.ptrTypeAligned(node),
|
.ptr_type_aligned => ptrTypeAligned(tree, node),
|
||||||
.ptr_type_sentinel => tree.ptrTypeSentinel(node),
|
.ptr_type_sentinel => ptrTypeSentinel(tree, node),
|
||||||
.ptr_type => tree.ptrType(node),
|
.ptr_type => ptrTypeSimple(tree, node),
|
||||||
.ptr_type_bit_range => tree.ptrTypeBitRange(node),
|
.ptr_type_bit_range => ptrTypeBitRange(tree, node),
|
||||||
else => null,
|
else => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fullIf(tree: Ast, node: Node.Index) ?full.If {
|
pub fn fullIf(tree: Ast, node: Node.Index) ?full.If {
|
||||||
return switch (tree.nodes.items(.tag)[node]) {
|
return switch (tree.nodes.items(.tag)[node]) {
|
||||||
.if_simple => tree.ifSimple(node),
|
.if_simple => ifSimple(tree, node),
|
||||||
.@"if" => tree.ifFull(node),
|
.@"if" => ifFull(tree, node),
|
||||||
else => null,
|
else => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While {
|
pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While {
|
||||||
return switch (tree.nodes.items(.tag)[node]) {
|
return switch (tree.nodes.items(.tag)[node]) {
|
||||||
.while_simple => tree.whileSimple(node),
|
.while_simple => whileSimple(tree, node),
|
||||||
.while_cont => tree.whileCont(node),
|
.while_cont => whileCont(tree, node),
|
||||||
.@"while" => tree.whileFull(node),
|
.@"while" => whileFull(tree, node),
|
||||||
.for_simple => tree.forSimple(node),
|
.for_simple => forSimple(tree, node),
|
||||||
.@"for" => tree.forFull(node),
|
.@"for" => forFull(tree, node),
|
||||||
else => null,
|
else => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -543,7 +543,9 @@ pub fn lastToken(tree: Ast, node: Ast.Node.Index) Ast.TokenIndex {
|
|||||||
n = tree.extra_data[cases.end - 1]; // last case
|
n = tree.extra_data[cases.end - 1]; // last case
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.container_decl_arg => {
|
.container_decl_arg,
|
||||||
|
.container_decl_arg_trailing,
|
||||||
|
=> {
|
||||||
const members = tree.extraData(datas[n].rhs, Node.SubRange);
|
const members = tree.extraData(datas[n].rhs, Node.SubRange);
|
||||||
if (members.end - members.start == 0) {
|
if (members.end - members.start == 0) {
|
||||||
end_offset += 3; // for the rparen + lbrace + rbrace
|
end_offset += 3; // for the rparen + lbrace + rbrace
|
||||||
@ -567,7 +569,6 @@ pub fn lastToken(tree: Ast, node: Ast.Node.Index) Ast.TokenIndex {
|
|||||||
},
|
},
|
||||||
.array_init_comma,
|
.array_init_comma,
|
||||||
.struct_init_comma,
|
.struct_init_comma,
|
||||||
.container_decl_arg_trailing,
|
|
||||||
.switch_comma,
|
.switch_comma,
|
||||||
=> {
|
=> {
|
||||||
if (datas[n].rhs != 0) {
|
if (datas[n].rhs != 0) {
|
||||||
|
@ -74,9 +74,7 @@ const Builder = struct {
|
|||||||
const starts = tree.tokens.items(.start);
|
const starts = tree.tokens.items(.start);
|
||||||
const next_start = starts[token];
|
const next_start = starts[token];
|
||||||
|
|
||||||
if (next_start < self.previous_position) {
|
if (next_start < self.previous_position) return;
|
||||||
return error.MovedBackwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.previous_token) |prev| {
|
if (self.previous_token) |prev| {
|
||||||
// Highlight gaps between AST nodes. These can contain comments or malformed code.
|
// Highlight gaps between AST nodes. These can contain comments or malformed code.
|
||||||
@ -182,6 +180,8 @@ const Builder = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn addDirect(self: *Builder, tok_type: TokenType, tok_mod: TokenModifiers, start: usize, length: usize) !void {
|
fn addDirect(self: *Builder, tok_type: TokenType, tok_mod: TokenModifiers, start: usize, length: usize) !void {
|
||||||
|
if (start < self.previous_position) return;
|
||||||
|
|
||||||
const text = self.handle.tree.source[self.previous_position..start];
|
const text = self.handle.tree.source[self.previous_position..start];
|
||||||
const delta = offsets.indexToPosition(text, text.len, self.encoding);
|
const delta = offsets.indexToPosition(text, text.len, self.encoding);
|
||||||
|
|
||||||
@ -261,13 +261,8 @@ fn colorIdentifierBasedOnType(builder: *Builder, type_node: analysis.TypeWithHan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const WriteTokensError = error{
|
|
||||||
OutOfMemory,
|
|
||||||
MovedBackwards,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// HACK self-hosted has not implemented async yet
|
/// HACK self-hosted has not implemented async yet
|
||||||
fn callWriteNodeTokens(allocator: std.mem.Allocator, args: anytype) WriteTokensError!void {
|
fn callWriteNodeTokens(allocator: std.mem.Allocator, args: anytype) error{OutOfMemory}!void {
|
||||||
if (zig_builtin.zig_backend == .other or zig_builtin.zig_backend == .stage1) {
|
if (zig_builtin.zig_backend == .other or zig_builtin.zig_backend == .stage1) {
|
||||||
const FrameSize = @sizeOf(@Frame(writeNodeTokens));
|
const FrameSize = @sizeOf(@Frame(writeNodeTokens));
|
||||||
var child_frame = try allocator.alignedAlloc(u8, std.Target.stack_align, FrameSize);
|
var child_frame = try allocator.alignedAlloc(u8, std.Target.stack_align, FrameSize);
|
||||||
@ -280,7 +275,7 @@ fn callWriteNodeTokens(allocator: std.mem.Allocator, args: anytype) WriteTokensE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeNodeTokens(builder: *Builder, maybe_node: ?Ast.Node.Index) WriteTokensError!void {
|
fn writeNodeTokens(builder: *Builder, maybe_node: ?Ast.Node.Index) error{OutOfMemory}!void {
|
||||||
const node = maybe_node orelse return;
|
const node = maybe_node orelse return;
|
||||||
|
|
||||||
const handle = builder.handle;
|
const handle = builder.handle;
|
||||||
@ -1010,10 +1005,7 @@ pub fn writeAllSemanticTokens(
|
|||||||
|
|
||||||
// reverse the ast from the root declarations
|
// reverse the ast from the root declarations
|
||||||
for (handle.tree.rootDecls()) |child| {
|
for (handle.tree.rootDecls()) |child| {
|
||||||
writeNodeTokens(&builder, child) catch |err| switch (err) {
|
try writeNodeTokens(&builder, child);
|
||||||
error.MovedBackwards => break,
|
|
||||||
else => |e| return e,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
try builder.finish();
|
try builder.finish();
|
||||||
return builder.toOwnedSlice();
|
return builder.toOwnedSlice();
|
||||||
|
@ -32,6 +32,18 @@ test "semantic tokens - comments" {
|
|||||||
// TODO more tests
|
// TODO more tests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "semantic tokens - string literals" {
|
||||||
|
// https://github.com/zigtools/zls/issues/921
|
||||||
|
try testSemanticTokens(
|
||||||
|
\\"
|
||||||
|
\\"",//
|
||||||
|
\\"":
|
||||||
|
,
|
||||||
|
// no idea if this output is correct but at least it doesn't crash
|
||||||
|
&.{ 1, 3, 3, 8, 0, 1, 0, 2, 4, 0, 0, 0, 2, 9, 0 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const file_uri = switch (builtin.os.tag) {
|
const file_uri = switch (builtin.os.tag) {
|
||||||
.windows => "file:///C:/test.zig",
|
.windows => "file:///C:/test.zig",
|
||||||
else => "file:///test.zig",
|
else => "file:///test.zig",
|
||||||
|
Loading…
Reference in New Issue
Block a user