* Add smoke tests for folding ranges * fix index out of bounds in foldingRanges closes #801 For invalid syntax trees, zig's parser seems to return bogus data where startToken > endToken, which then causes everything else to crash. This seems like a deeper issue, which needs to be fixed "properly", but let's just paper over it here.
This commit is contained in:
parent
3ab859a304
commit
cfb0b023ad
@ -2454,7 +2454,7 @@ fn foldingRangeHandler(server: *Server, writer: anytype, id: types.RequestId, re
|
||||
end: Ast.TokenIndex,
|
||||
end_reach: Inclusivity,
|
||||
) std.mem.Allocator.Error!bool {
|
||||
const can_add = !tree.tokensOnSameLine(start, end);
|
||||
const can_add = start < end and !tree.tokensOnSameLine(start, end);
|
||||
if (can_add) {
|
||||
try addTokRange(p_ranges, tree, start, end, end_reach);
|
||||
}
|
||||
|
66
tests/lsp_features/folding_range.zig
Normal file
66
tests/lsp_features/folding_range.zig
Normal file
@ -0,0 +1,66 @@
|
||||
const std = @import("std");
|
||||
const zls = @import("zls");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const Context = @import("../context.zig").Context;
|
||||
|
||||
const types = zls.types;
|
||||
const requests = zls.requests;
|
||||
|
||||
const allocator: std.mem.Allocator = std.testing.allocator;
|
||||
|
||||
test "foldingRange - empty" {
|
||||
try testFoldingRange("", "[]");
|
||||
}
|
||||
|
||||
test "foldingRange - smoke" {
|
||||
try testFoldingRange(
|
||||
\\fn main() u32 {
|
||||
\\ return 1 + 1;
|
||||
\\}
|
||||
,
|
||||
\\[{"startLine":0,"endLine":1}]
|
||||
);
|
||||
}
|
||||
|
||||
test "foldingRange - #801" {
|
||||
try testFoldingRange(
|
||||
\\fn score(c: u8) !u32 {
|
||||
\\ return switch(c) {
|
||||
\\ 'a'...'z' => c - 'a',
|
||||
\\ 'A'...'Z' => c - 'A',
|
||||
\\ _ => error
|
||||
\\ };
|
||||
\\}
|
||||
,
|
||||
\\[]
|
||||
);
|
||||
}
|
||||
|
||||
fn testFoldingRange(source: []const u8, expect: []const u8) !void {
|
||||
var ctx = try Context.init();
|
||||
defer ctx.deinit();
|
||||
|
||||
const test_uri: []const u8 = switch (builtin.os.tag) {
|
||||
.windows => "file:///C:\\test.zig",
|
||||
else => "file:///test.zig",
|
||||
};
|
||||
|
||||
try ctx.requestDidOpen(test_uri, source);
|
||||
|
||||
const request = requests.FoldingRange{ .params = .{ .textDocument = .{ .uri = test_uri } } };
|
||||
|
||||
const response = try ctx.requestGetResponse(?[]types.FoldingRange, "textDocument/foldingRange", request);
|
||||
defer response.deinit();
|
||||
|
||||
var actual = std.ArrayList(u8).init(allocator);
|
||||
defer actual.deinit();
|
||||
|
||||
try std.json.stringify(response.result, .{}, actual.writer());
|
||||
try expectEqualJson(expect, actual.items);
|
||||
}
|
||||
|
||||
fn expectEqualJson(expect: []const u8, actual: []const u8) !void {
|
||||
// TODO: Actually compare strings as JSON values.
|
||||
return std.testing.expectEqualStrings(expect, actual);
|
||||
}
|
@ -10,11 +10,12 @@ comptime {
|
||||
// TODO Document Synchronization
|
||||
|
||||
// LSP features
|
||||
_ = @import("lsp_features/semantic_tokens.zig");
|
||||
_ = @import("lsp_features/completion.zig");
|
||||
_ = @import("lsp_features/folding_range.zig");
|
||||
_ = @import("lsp_features/inlay_hints.zig");
|
||||
_ = @import("lsp_features/references.zig");
|
||||
_ = @import("lsp_features/completion.zig");
|
||||
_ = @import("lsp_features/selection_range.zig");
|
||||
_ = @import("lsp_features/semantic_tokens.zig");
|
||||
|
||||
// Language features
|
||||
_ = @import("language_features/cimport.zig");
|
||||
|
Loading…
Reference in New Issue
Block a user