optimize folding range (#926)
This commit is contained in:
parent
ea05916e69
commit
5afaf2ae3a
@ -2508,6 +2508,9 @@ fn inlayHintHandler(server: *Server, request: types.InlayHintParams) Error!?[]ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[]types.CodeAction {
|
fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[]types.CodeAction {
|
||||||
|
const tracy_zone = tracy.trace(@src());
|
||||||
|
defer tracy_zone.end();
|
||||||
|
|
||||||
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
|
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
|
||||||
|
|
||||||
var builder = code_actions.Builder{
|
var builder = code_actions.Builder{
|
||||||
@ -2536,6 +2539,9 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error!?[]types.FoldingRange {
|
fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error!?[]types.FoldingRange {
|
||||||
|
const tracy_zone = tracy.trace(@src());
|
||||||
|
defer tracy_zone.end();
|
||||||
|
|
||||||
const Token = std.zig.Token;
|
const Token = std.zig.Token;
|
||||||
const Node = Ast.Node;
|
const Node = Ast.Node;
|
||||||
const allocator = server.arena.allocator();
|
const allocator = server.arena.allocator();
|
||||||
@ -2543,37 +2549,26 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
|
|
||||||
const helper = struct {
|
const helper = struct {
|
||||||
const Inclusivity = enum { inclusive, exclusive };
|
const Inclusivity = enum { inclusive, exclusive };
|
||||||
/// Returns true if added.
|
|
||||||
fn maybeAddTokRange(
|
|
||||||
p_ranges: *std.ArrayList(types.FoldingRange),
|
|
||||||
tree: Ast,
|
|
||||||
start: Ast.TokenIndex,
|
|
||||||
end: Ast.TokenIndex,
|
|
||||||
end_reach: Inclusivity,
|
|
||||||
encoding: offsets.Encoding,
|
|
||||||
) std.mem.Allocator.Error!bool {
|
|
||||||
const can_add = start < end and !tree.tokensOnSameLine(start, end);
|
|
||||||
if (can_add) {
|
|
||||||
try addTokRange(p_ranges, tree, start, end, end_reach, encoding);
|
|
||||||
}
|
|
||||||
return can_add;
|
|
||||||
}
|
|
||||||
fn addTokRange(
|
fn addTokRange(
|
||||||
p_ranges: *std.ArrayList(types.FoldingRange),
|
p_ranges: *std.ArrayList(types.FoldingRange),
|
||||||
tree: Ast,
|
tree: Ast,
|
||||||
start: Ast.TokenIndex,
|
start: Ast.TokenIndex,
|
||||||
end: Ast.TokenIndex,
|
end: Ast.TokenIndex,
|
||||||
end_reach: Inclusivity,
|
end_reach: Inclusivity,
|
||||||
encoding: offsets.Encoding,
|
|
||||||
) std.mem.Allocator.Error!void {
|
) std.mem.Allocator.Error!void {
|
||||||
std.debug.assert(!std.debug.runtime_safety or !tree.tokensOnSameLine(start, end));
|
if (tree.tokensOnSameLine(start, end)) return;
|
||||||
|
std.debug.assert(start <= end);
|
||||||
|
|
||||||
const start_line = offsets.tokenToPosition(tree, start, encoding).line;
|
const start_index = offsets.tokenToIndex(tree, start);
|
||||||
const end_line = offsets.tokenToPosition(tree, end, encoding).line;
|
const end_index = offsets.tokenToIndex(tree, end);
|
||||||
|
|
||||||
|
const start_line = std.mem.count(u8, tree.source[0..start_index], "\n");
|
||||||
|
const end_line = start_line + std.mem.count(u8, tree.source[start_index..end_index], "\n");
|
||||||
|
|
||||||
try p_ranges.append(.{
|
try p_ranges.append(.{
|
||||||
.startLine = start_line,
|
.startLine = @intCast(u32, start_line),
|
||||||
.endLine = end_line - @boolToInt(end_reach == .exclusive),
|
.endLine = @intCast(u32, end_line) - @boolToInt(end_reach == .exclusive),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -2604,6 +2599,7 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
const node = @intCast(Node.Index, i);
|
const node = @intCast(Node.Index, i);
|
||||||
|
|
||||||
switch (node_tag) {
|
switch (node_tag) {
|
||||||
|
.root => continue,
|
||||||
// only fold the expression pertaining to the if statement, and the else statement, each respectively.
|
// only fold the expression pertaining to the if statement, and the else statement, each respectively.
|
||||||
// TODO: Should folding multiline condition expressions also be supported? Ditto for the other control flow structures.
|
// TODO: Should folding multiline condition expressions also be supported? Ditto for the other control flow structures.
|
||||||
.@"if", .if_simple => {
|
.@"if", .if_simple => {
|
||||||
@ -2611,14 +2607,14 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
|
|
||||||
const start_tok_1 = ast.lastToken(handle.tree, if_full.ast.cond_expr);
|
const start_tok_1 = ast.lastToken(handle.tree, if_full.ast.cond_expr);
|
||||||
const end_tok_1 = ast.lastToken(handle.tree, if_full.ast.then_expr);
|
const end_tok_1 = ast.lastToken(handle.tree, if_full.ast.then_expr);
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_tok_1, end_tok_1, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_tok_1, end_tok_1, .inclusive);
|
||||||
|
|
||||||
if (if_full.ast.else_expr == 0) continue;
|
if (if_full.ast.else_expr == 0) continue;
|
||||||
|
|
||||||
const start_tok_2 = if_full.else_token;
|
const start_tok_2 = if_full.else_token;
|
||||||
const end_tok_2 = ast.lastToken(handle.tree, if_full.ast.else_expr);
|
const end_tok_2 = ast.lastToken(handle.tree, if_full.ast.else_expr);
|
||||||
|
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_tok_2, end_tok_2, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_tok_2, end_tok_2, .inclusive);
|
||||||
},
|
},
|
||||||
|
|
||||||
// same as if/else
|
// same as if/else
|
||||||
@ -2632,13 +2628,13 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
|
|
||||||
const start_tok_1 = ast.lastToken(handle.tree, loop_full.ast.cond_expr);
|
const start_tok_1 = ast.lastToken(handle.tree, loop_full.ast.cond_expr);
|
||||||
const end_tok_1 = ast.lastToken(handle.tree, loop_full.ast.then_expr);
|
const end_tok_1 = ast.lastToken(handle.tree, loop_full.ast.then_expr);
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_tok_1, end_tok_1, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_tok_1, end_tok_1, .inclusive);
|
||||||
|
|
||||||
if (loop_full.ast.else_expr == 0) continue;
|
if (loop_full.ast.else_expr == 0) continue;
|
||||||
|
|
||||||
const start_tok_2 = loop_full.else_token;
|
const start_tok_2 = loop_full.else_token;
|
||||||
const end_tok_2 = ast.lastToken(handle.tree, loop_full.ast.else_expr);
|
const end_tok_2 = ast.lastToken(handle.tree, loop_full.ast.else_expr);
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_tok_2, end_tok_2, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_tok_2, end_tok_2, .inclusive);
|
||||||
},
|
},
|
||||||
|
|
||||||
.global_var_decl,
|
.global_var_decl,
|
||||||
@ -2666,7 +2662,7 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
start_doc_tok -= 1;
|
start_doc_tok -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_doc_tok, end_doc_tok, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_doc_tok, end_doc_tok, .inclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function prototype folding regions
|
// Function prototype folding regions
|
||||||
@ -2678,10 +2674,7 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
const list_end_tok: Ast.TokenIndex = ast.lastToken(handle.tree, fn_proto.ast.proto_node);
|
const list_end_tok: Ast.TokenIndex = ast.lastToken(handle.tree, fn_proto.ast.proto_node);
|
||||||
|
|
||||||
if (handle.tree.tokensOnSameLine(list_start_tok, list_end_tok)) break :decl_node_blk;
|
if (handle.tree.tokensOnSameLine(list_start_tok, list_end_tok)) break :decl_node_blk;
|
||||||
try ranges.ensureUnusedCapacity(1 + fn_proto.ast.params.len); // best guess, doesn't include anytype params
|
try helper.addTokRange(&ranges, handle.tree, list_start_tok, list_end_tok, .exclusive);
|
||||||
helper.addTokRange(&ranges, handle.tree, list_start_tok, list_end_tok, .exclusive, server.offset_encoding) catch |err| switch (err) {
|
|
||||||
error.OutOfMemory => unreachable,
|
|
||||||
};
|
|
||||||
|
|
||||||
var it = fn_proto.iterate(&handle.tree);
|
var it = fn_proto.iterate(&handle.tree);
|
||||||
while (ast.nextFnParam(&it)) |param| {
|
while (ast.nextFnParam(&it)) |param| {
|
||||||
@ -2691,7 +2684,7 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
while (token_tags[doc_end_tok + 1] == .doc_comment)
|
while (token_tags[doc_end_tok + 1] == .doc_comment)
|
||||||
doc_end_tok += 1;
|
doc_end_tok += 1;
|
||||||
|
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, doc_start_tok, doc_end_tok, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, doc_start_tok, doc_end_tok, .inclusive);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2703,7 +2696,7 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
=> {
|
=> {
|
||||||
const start_tok = handle.tree.firstToken(node);
|
const start_tok = handle.tree.firstToken(node);
|
||||||
const end_tok = ast.lastToken(handle.tree, node);
|
const end_tok = ast.lastToken(handle.tree, node);
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_tok, end_tok, .inclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_tok, end_tok, .inclusive);
|
||||||
},
|
},
|
||||||
|
|
||||||
// most other trivial cases can go through here.
|
// most other trivial cases can go through here.
|
||||||
@ -2750,7 +2743,7 @@ fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error
|
|||||||
|
|
||||||
const start_tok = handle.tree.firstToken(node);
|
const start_tok = handle.tree.firstToken(node);
|
||||||
const end_tok = ast.lastToken(handle.tree, node);
|
const end_tok = ast.lastToken(handle.tree, node);
|
||||||
_ = try helper.maybeAddTokRange(&ranges, handle.tree, start_tok, end_tok, .exclusive, server.offset_encoding);
|
try helper.addTokRange(&ranges, handle.tree, start_tok, end_tok, .exclusive);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2799,6 +2792,9 @@ pub const SelectionRange = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn selectionRangeHandler(server: *Server, request: types.SelectionRangeParams) Error!?[]*SelectionRange {
|
fn selectionRangeHandler(server: *Server, request: types.SelectionRangeParams) Error!?[]*SelectionRange {
|
||||||
|
const tracy_zone = tracy.trace(@src());
|
||||||
|
defer tracy_zone.end();
|
||||||
|
|
||||||
const allocator = server.arena.allocator();
|
const allocator = server.arena.allocator();
|
||||||
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
|
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user