Add super basic unused variable support
This commit is contained in:
parent
cad9b0aba2
commit
e5e76c8063
93
src/main.zig
93
src/main.zig
@ -229,11 +229,66 @@ fn publishDiagnostics(arena: *std.heap.ArenaAllocator, handle: DocumentStore.Han
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (handle.document_scope.scopes) |scope| {
|
||||||
|
const scope_data = switch (scope.data) {
|
||||||
|
.function => |f| f,
|
||||||
|
.block => |b| b,
|
||||||
|
else => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
var decl_iterator = scope.decls.iterator();
|
||||||
|
while (decl_iterator.next()) |decl| {
|
||||||
|
var identifier_count: usize = 0;
|
||||||
|
|
||||||
|
var name_token_index = switch (decl.value_ptr.*) {
|
||||||
|
.ast_node => |an| s: {
|
||||||
|
const an_tag = tree.nodes.items(.tag)[an];
|
||||||
|
switch (an_tag) {
|
||||||
|
.simple_var_decl => {
|
||||||
|
break :s tree.nodes.items(.main_token)[an] + 1;
|
||||||
|
},
|
||||||
|
else => continue,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.param_decl => |param| param.name_token orelse continue,
|
||||||
|
else => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
const pit_start = tree.firstToken(scope_data);
|
||||||
|
const pit_end = ast.lastToken(tree, scope_data);
|
||||||
|
|
||||||
|
for (tree.tokens.items(.tag)[pit_start..pit_end]) |tag, index| {
|
||||||
|
if (tag == .identifier and std.mem.eql(u8, tree.tokenSlice(pit_start + @intCast(u32, index)), tree.tokenSlice(name_token_index))) identifier_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifier_count <= 1)
|
||||||
|
try diagnostics.append(.{
|
||||||
|
.range = astLocationToRange(tree.tokenLocation(0, name_token_index)),
|
||||||
|
.severity = .Error,
|
||||||
|
.code = "unused_variable",
|
||||||
|
.source = "zls",
|
||||||
|
.message = "Unused variable! Either remove the variable or use '_ = ' on the variable to bypass this error.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: style warnings for types, values and declarations below root scope
|
// TODO: style warnings for types, values and declarations below root scope
|
||||||
if (tree.errors.len == 0) {
|
if (tree.errors.len == 0) {
|
||||||
for (tree.rootDecls()) |decl_idx| {
|
for (tree.rootDecls()) |decl_idx| {
|
||||||
const decl = tree.nodes.items(.tag)[decl_idx];
|
const decl = tree.nodes.items(.tag)[decl_idx];
|
||||||
switch (decl) {
|
switch (decl) {
|
||||||
|
// .simple_var_decl => {
|
||||||
|
// // var d = ast.varDecl(tree, decl_idx).?;
|
||||||
|
// const loc = tree.tokenLocation(0, decl_idx);
|
||||||
|
|
||||||
|
// try diagnostics.append(.{
|
||||||
|
// .range = astLocationToRange(loc),
|
||||||
|
// .severity = .Information,
|
||||||
|
// .code = "unused_variable",
|
||||||
|
// .source = "zls",
|
||||||
|
// .message = "Unused variable",
|
||||||
|
// });
|
||||||
|
// },
|
||||||
.fn_proto,
|
.fn_proto,
|
||||||
.fn_proto_multi,
|
.fn_proto_multi,
|
||||||
.fn_proto_one,
|
.fn_proto_one,
|
||||||
@ -255,7 +310,7 @@ fn publishDiagnostics(arena: *std.heap.ArenaAllocator, handle: DocumentStore.Han
|
|||||||
try diagnostics.append(.{
|
try diagnostics.append(.{
|
||||||
.range = astLocationToRange(loc),
|
.range = astLocationToRange(loc),
|
||||||
.severity = .Information,
|
.severity = .Information,
|
||||||
.code = "BadStyle",
|
.code = "bad-style",
|
||||||
.source = "zls",
|
.source = "zls",
|
||||||
.message = "Functions should be camelCase",
|
.message = "Functions should be camelCase",
|
||||||
});
|
});
|
||||||
@ -263,7 +318,7 @@ fn publishDiagnostics(arena: *std.heap.ArenaAllocator, handle: DocumentStore.Han
|
|||||||
try diagnostics.append(.{
|
try diagnostics.append(.{
|
||||||
.range = astLocationToRange(loc),
|
.range = astLocationToRange(loc),
|
||||||
.severity = .Information,
|
.severity = .Information,
|
||||||
.code = "BadStyle",
|
.code = "bad-style",
|
||||||
.source = "zls",
|
.source = "zls",
|
||||||
.message = "Type functions should be PascalCase",
|
.message = "Type functions should be PascalCase",
|
||||||
});
|
});
|
||||||
@ -1192,7 +1247,7 @@ fn completeFieldAccess(arena: *std.heap.ArenaAllocator, id: types.RequestId, han
|
|||||||
truncateCompletions(completions.items, config.max_detail_length);
|
truncateCompletions(completions.items, config.max_detail_length);
|
||||||
if (client_capabilities.label_details_support) {
|
if (client_capabilities.label_details_support) {
|
||||||
for (completions.items) |*item| {
|
for (completions.items) |*item| {
|
||||||
try formatDetailledLabel(item, arena.allocator());
|
try formatDetailledLabel(item, arena.allocator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1375,7 +1430,6 @@ fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) !
|
|||||||
// logger.info("labelDetails: {s} :: {s}", .{item.labelDetails.?.detail, item.labelDetails.?.description});
|
// logger.info("labelDetails: {s} :: {s}", .{item.labelDetails.?.detail, item.labelDetails.?.description});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn completeError(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: *DocumentStore.Handle, config: *const Config) !void {
|
fn completeError(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: *DocumentStore.Handle, config: *const Config) !void {
|
||||||
const tracy_zone = tracy.trace(@src());
|
const tracy_zone = tracy.trace(@src());
|
||||||
defer tracy_zone.end();
|
defer tracy_zone.end();
|
||||||
@ -1396,25 +1450,24 @@ fn completeError(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: *
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kindToSortScore(kind: types.CompletionItem.Kind) [] const u8 {
|
fn kindToSortScore(kind: types.CompletionItem.Kind) []const u8 {
|
||||||
return switch (kind)
|
return switch (kind) {
|
||||||
{
|
|
||||||
.Constant => "1_",
|
.Constant => "1_",
|
||||||
|
|
||||||
.Variable => "2_",
|
.Variable => "2_",
|
||||||
.Field => "3_",
|
.Field => "3_",
|
||||||
.Function => "4_",
|
.Function => "4_",
|
||||||
|
|
||||||
.Keyword,
|
.Keyword, .EnumMember => "5_",
|
||||||
.EnumMember => "5_",
|
|
||||||
|
|
||||||
.Class,
|
.Class,
|
||||||
.Interface,
|
.Interface,
|
||||||
.Struct,
|
.Struct,
|
||||||
// Union?
|
// Union?
|
||||||
.TypeParameter => "6_",
|
.TypeParameter,
|
||||||
|
=> "6_",
|
||||||
else => "9_"
|
|
||||||
|
else => "9_",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1422,10 +1475,10 @@ fn sortCompletionItems(completions: []types.CompletionItem, _: *const Config, al
|
|||||||
// TODO: config for sorting rule?
|
// TODO: config for sorting rule?
|
||||||
for (completions) |*c| {
|
for (completions) |*c| {
|
||||||
c.sortText = kindToSortScore(c.kind);
|
c.sortText = kindToSortScore(c.kind);
|
||||||
|
|
||||||
if (alloc.alloc(u8, 2 + c.label.len)) |it| {
|
if (alloc.alloc(u8, 2 + c.label.len)) |it| {
|
||||||
std.mem.copy(u8, it, c.sortText.?);
|
std.mem.copy(u8, it, c.sortText.?);
|
||||||
std.mem.copy(u8, it[2 .. ], c.label);
|
std.mem.copy(u8, it[2..], c.label);
|
||||||
c.sortText = it;
|
c.sortText = it;
|
||||||
} else |_| {}
|
} else |_| {}
|
||||||
}
|
}
|
||||||
@ -1554,13 +1607,7 @@ fn initializeHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req:
|
|||||||
},
|
},
|
||||||
.textDocumentSync = .Full,
|
.textDocumentSync = .Full,
|
||||||
.renameProvider = true,
|
.renameProvider = true,
|
||||||
.completionProvider = .{
|
.completionProvider = .{ .resolveProvider = false, .triggerCharacters = &[_][]const u8{ ".", ":", "@" }, .completionItem = .{ .labelDetailsSupport = true } },
|
||||||
.resolveProvider = false,
|
|
||||||
.triggerCharacters = &[_][]const u8{ ".", ":", "@" },
|
|
||||||
.completionItem = .{
|
|
||||||
.labelDetailsSupport = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.documentHighlightProvider = false,
|
.documentHighlightProvider = false,
|
||||||
.hoverProvider = true,
|
.hoverProvider = true,
|
||||||
.codeActionProvider = false,
|
.codeActionProvider = false,
|
||||||
|
@ -251,11 +251,11 @@ pub const CompletionItem = struct {
|
|||||||
|
|
||||||
insertTextFormat: ?InsertTextFormat = .PlainText,
|
insertTextFormat: ?InsertTextFormat = .PlainText,
|
||||||
documentation: ?MarkupContent = null,
|
documentation: ?MarkupContent = null,
|
||||||
|
|
||||||
// FIXME: i commented this out, because otherwise the vscode client complains about *ranges*
|
// FIXME: i commented this out, because otherwise the vscode client complains about *ranges*
|
||||||
// and breaks code completion entirely
|
// and breaks code completion entirely
|
||||||
// see: https://github.com/zigtools/zls-vscode/pull/33
|
// see: https://github.com/zigtools/zls-vscode/pull/33
|
||||||
// textEdit: ?TextEdit = null,
|
// textEdit: ?TextEdit = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CompletionItemLabelDetails = struct {
|
pub const CompletionItemLabelDetails = struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user