expand dot completions

This commit is contained in:
Techatrix 2023-01-23 21:28:15 +01:00
parent 723592e2ed
commit d10837dca0

View File

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const InternPool = @import("InternPool.zig"); const InternPool = @import("../InternPool.zig");
const types = @import("lsp.zig"); const types = @import("../lsp.zig");
const Ast = std.zig.Ast; const Ast = std.zig.Ast;
@ -8,41 +8,57 @@ pub fn dotCompletions(
arena: std.mem.Allocator, arena: std.mem.Allocator,
ip: *InternPool, ip: *InternPool,
ty: InternPool.Index, ty: InternPool.Index,
/// used for extracting doc comments val: InternPool.Index,
node: ?Ast.Node.Index, node: ?Ast.Node.Index
) error{OutOfMemory}![]types.CompletionItem {
return try dotCompletionsInternal(arena, ip, ty, node);
}
pub fn dotCompletionsInternal(
arena: std.mem.Allocator,
ip: *InternPool,
ty: InternPool.Index,
node: ?Ast.Node.Index,
follow_one_pointer: bool,
) error{OutOfMemory}![]types.CompletionItem { ) error{OutOfMemory}![]types.CompletionItem {
_ = node; _ = node;
var completions = std.ArrayListUnmanaged(types.CompletionItem){}; var completions = std.ArrayListUnmanaged(types.CompletionItem){};
switch (ip.indexToKey(ty)) {
.simple => {},
.int_type => {}, const key = ip.indexToKey(ty);
.pointer_type => |pointer_info| { const inner_key = switch (key) {
switch (pointer_info.size) { .pointer_type => |info| if (info.size == .One) ip.indexToKey(info.elem_type) else key,
.One => { else => key,
};
switch (inner_key) {
.simple => |simple| switch (simple) {
.type => {
const ty_key = ip.indexToKey(val);
if (ty_key.getNamespace()) {
// TODO lookup in namespace
}
switch (ty_key) {
.error_set_type => |error_set_info| {
for (error_set_info.names) |name| {
const error_name = ip.indexToKey(name).bytes;
try completions.append(arena, .{ try completions.append(arena, .{
.label = "*", .label = error_name,
.kind = .Operator, .kind = .Constant,
.detail = std.fmt.allocPrint(arena, "{}", .{pointer_info.elem_type.fmtType(ip)}), .detail = std.fmt.allocPrint(arena, "error.{s}", .{std.zig.fmtId(error_name)}),
}); });
if (follow_one_pointer) {
try dotCompletionsInternal(arena, ip, pointer_info.elem_type, false);
} }
}, },
.Slice => { .union_type => {}, // TODO
.enum_type => |enum_info|{
for (enum_info.fields) |field| {
const field_name = ip.indexToKey(field.name).bytes;
try completions.append(arena, .{
.label = field_name,
.kind = .Constant,
// include field.val?
});
}
},
else => {},
}
},
else => false,
},
.pointer_type => |pointer_info| {
if (pointer_info == .Slice) {
var many_ptr_info = InternPool.Key{ .pointer_type = pointer_info }; var many_ptr_info = InternPool.Key{ .pointer_type = pointer_info };
many_ptr_info.pointer_info.size = .Many; many_ptr_info.pointer_type.size = .Many;
try completions.append(arena, .{ try completions.append(arena, .{
.label = "ptr", .label = "ptr",
@ -54,10 +70,12 @@ pub fn dotCompletionsInternal(
.kind = .Field, .kind = .Field,
.detail = "usize", .detail = "usize",
}); });
}, } else if(ip.indexToKey(pointer_info.elem_type) == .array_type) {
.Many, try completions.append(arena, .{
.C, .label = "len",
=> {}, .kind = .Field,
.detail = "usize",
});
} }
}, },
.array_type => |array_info| { .array_type => |array_info| {
@ -70,14 +88,14 @@ pub fn dotCompletionsInternal(
}, },
.struct_type => |struct_info| { .struct_type => |struct_info| {
for (struct_info.fields) |field| { for (struct_info.fields) |field| {
const field_name = ip.indexToKey(field.name).bytes;
try completions.append(arena, types.CompletionItem{ try completions.append(arena, types.CompletionItem{
.label = field.name, .label = field_name,
.kind = .Field, .kind = .Field,
// TODO include alignment and comptime // TODO include alignment and comptime
.detail = std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}), .detail = std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}),
}); });
} }
// TODO namespace
}, },
.optional_type => |optional_info| { .optional_type => |optional_info| {
try completions.append(arena, .{ try completions.append(arena, .{
@ -86,31 +104,21 @@ pub fn dotCompletionsInternal(
.detail = std.fmt.allocPrint(arena, "{}", .{optional_info.payload_type.fmtType(ip)}), .detail = std.fmt.allocPrint(arena, "{}", .{optional_info.payload_type.fmtType(ip)}),
}); });
}, },
.error_union_type => {},
.error_set_type => |error_set_info| {
for (error_set_info.names) |name| {
try completions.append(arena, .{
.label = name,
.kind = .Constant,
.detail = std.fmt.allocPrint(arena, "error.{s}", .{name}),
});
}
},
.enum_type => |enum_info| { .enum_type => |enum_info| {
for (enum_info.fields) |field| { for (enum_info.fields) |field| {
const field_name = ip.indexToKey(field.name).bytes;
try completions.append(arena, .{ try completions.append(arena, .{
.label = field.name, .label = field_name,
.kind = .Field, .kind = .Field,
.detail = std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}), .detail = std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}),
}); });
} }
// TODO namespace
}, },
.function_type => {},
.union_type => |union_info| { .union_type => |union_info| {
for (union_info.fields) |field| { for (union_info.fields) |field| {
const field_name = ip.indexToKey(field.name).bytes;
try completions.append(arena, .{ try completions.append(arena, .{
.label = field.name, .label = field_name,
.kind = .Field, .kind = .Field,
.detail = if (field.alignment != 0) .detail = if (field.alignment != 0)
std.fmt.allocPrint(arena, "align({d}) {}", .{ field.alignment, field.ty.fmtType(ip) }) std.fmt.allocPrint(arena, "align({d}) {}", .{ field.alignment, field.ty.fmtType(ip) })
@ -118,12 +126,20 @@ pub fn dotCompletionsInternal(
std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}), std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}),
}); });
} }
// TODO namespace
}, },
.tuple_type => { .tuple_type => |tuple_info| {
// TODO for (tuple_info.types) |tuple_ty,i| {
try completions.append(arena, .{
.label = std.fmt.allocPrint(arena, "{d}", .{i}),
.kind = .Field,
.detail = std.fmt.allocPrint(arena, "{}", .{tuple_ty.fmtType(ip)}),
});
}
}, },
.vector_type => {}, .int_type,
.error_union_type,
.function_type,
.vector_type,
.anyframe_type => {}, .anyframe_type => {},
.int_u64_value, .int_u64_value,
@ -134,12 +150,12 @@ pub fn dotCompletionsInternal(
.float_64_value, .float_64_value,
.float_80_value, .float_80_value,
.float_128_value, .float_128_value,
=> {}, => unreachable,
.bytes, .bytes,
.aggregate, .aggregate,
.union_value, .union_value,
=> {}, => unreachable,
} }
return try completions.toOwnedSlice(arena); return try completions.toOwnedSlice(arena);
} }