Add rename file

This commit is contained in:
Alexandros Naskos 2020-06-27 09:18:05 +03:00
parent beb900f1d9
commit 07e1013680

50
src/rename.zig Normal file
View File

@ -0,0 +1,50 @@
const std = @import("std");
const DocumentStore = @import("document_store.zig");
const analysis = @import("analysis.zig");
const types = @import("types.zig");
fn renameToken(handle: *DocumentStore.Handle, tok: std.zig.ast.TokenIndex, new_name: []const u8, edits: *std.ArrayList(types.TextEdit)) !void {
// const handle.tree.tokenLocation(start_index: usize, token: Token.Loc)
const loc = handle.tree.tokenLocation(0, tok);
(try edits.addOne()).* = .{
.range = .{
.start = .{
.line = @intCast(types.Integer, loc.line),
.character = @intCast(types.Integer, loc.column),
},
.end = .{
.line = @intCast(types.Integer, loc.line),
.character = @intCast(types.Integer, loc.column + handle.tree.token_locs[tok].end - handle.tree.token_locs[tok].start),
},
},
.newText = new_name,
};
}
pub fn renameLabel(arena: *std.heap.ArenaAllocator, decl: analysis.DeclWithHandle, new_name: []const u8, edits: *std.StringHashMap([]types.TextEdit)) !void {
std.debug.assert(decl.decl.* == .label_decl);
const handle = decl.handle;
var text_edits = std.ArrayList(types.TextEdit).init(&arena.allocator);
// Find while / for / block from label -> iterate over children nodes, find break and continues, change their labels if they match.
// This case can be implemented just by scanning tokens.
const first_tok = decl.decl.label_decl.firstToken();
const last_tok = decl.decl.label_decl.lastToken();
// The first token is always going to be the label
try renameToken(handle, first_tok, new_name, &text_edits);
var curr_tok = first_tok + 1;
while (curr_tok < last_tok - 2) : (curr_tok += 1) {
if (handle.tree.token_ids[curr_tok] == .Keyword_break and handle.tree.token_ids[curr_tok + 1] == .Colon and
handle.tree.token_ids[curr_tok + 2] == .Identifier)
{
if (std.mem.eql(u8, handle.tree.tokenSlice(curr_tok + 2), handle.tree.tokenSlice(first_tok))) {
try renameToken(handle, curr_tok + 2, new_name, &text_edits);
}
}
}
try edits.putNoClobber(handle.uri(), text_edits.items);
}