use analyser/completions.zig for completing comptime interpreter

This commit is contained in:
Techatrix 2023-01-23 22:23:01 +01:00
parent 4b7a434feb
commit 829f4aa9c4
4 changed files with 28 additions and 48 deletions

View File

@ -31,8 +31,7 @@ pub const Pointer = packed struct {
}; };
pub const Array = packed struct { pub const Array = packed struct {
// TODO change to Index len: u64,
len: u32,
child: Index, child: Index,
sentinel: Index = .none, sentinel: Index = .none,
}; };

View File

@ -20,6 +20,7 @@ const tracy = @import("tracy.zig");
const uri_utils = @import("uri.zig"); const uri_utils = @import("uri.zig");
const diff = @import("diff.zig"); const diff = @import("diff.zig");
const ComptimeInterpreter = @import("ComptimeInterpreter.zig"); const ComptimeInterpreter = @import("ComptimeInterpreter.zig");
const analyser_completions = @import("analyser/completions.zig");
const data = @import("data/data.zig"); const data = @import("data/data.zig");
const snipped_data = @import("data/snippets.zig"); const snipped_data = @import("data/snippets.zig");
@ -595,24 +596,8 @@ fn typeToCompletion(
), ),
.primitive, .array_index => {}, .primitive, .array_index => {},
.@"comptime" => |co| { .@"comptime" => |co| {
const key = co.interpreter.ip.indexToKey(co.type.ty); const items = try analyser_completions.dotCompletions(allocator, &co.interpreter.ip, co.value.ty, co.value.val, co.value.node_idx);
try list.appendSlice(allocator, items);
switch (key) {
.struct_type => |struct_info| {
for (struct_info.fields) |field| {
const field_name = co.interpreter.ip.indexToKey(field.name).bytes;
try list.append(allocator, .{
.label = field_name,
.kind = .Field,
.insertText = field_name,
.insertTextFormat = .PlainText,
});
}
// TODO declaration completion
},
else => {},
}
}, },
} }
} }
@ -934,7 +919,7 @@ fn hoverSymbol(server: *Server, decl_handle: analysis.DeclWithHandle) error{OutO
const resolved_type_str = if (resolved_type) |rt| const resolved_type_str = if (resolved_type) |rt|
if (rt.type.is_type_val) switch (rt.type.data) { if (rt.type.is_type_val) switch (rt.type.data) {
.@"comptime" => |*co| try std.fmt.allocPrint(server.arena.allocator(), "{}", .{co.type.ty.fmtType(co.interpreter.ip)}), .@"comptime" => |co| try std.fmt.allocPrint(server.arena.allocator(), "{}", .{co.value.ty.fmtType(co.interpreter.ip)}),
else => "type", else => "type",
} else switch (rt.type.data) { // TODO: Investigate random weird numbers like 897 that cause index of bounds } else switch (rt.type.data) { // TODO: Investigate random weird numbers like 897 that cause index of bounds
.pointer, .pointer,

View File

@ -4,6 +4,8 @@ const types = @import("../lsp.zig");
const Ast = std.zig.Ast; const Ast = std.zig.Ast;
/// TODO use std.ArrayListUnmanaged instead of returning a slice
pub fn dotCompletions( pub fn dotCompletions(
arena: std.mem.Allocator, arena: std.mem.Allocator,
ip: *InternPool, ip: *InternPool,
@ -25,7 +27,8 @@ pub fn dotCompletions(
.simple => |simple| switch (simple) { .simple => |simple| switch (simple) {
.type => { .type => {
const ty_key = ip.indexToKey(val); const ty_key = ip.indexToKey(val);
if (ty_key.getNamespace()) { const namespace = ty_key.getNamespace();
if (namespace != .none) {
// TODO lookup in namespace // TODO lookup in namespace
} }
switch (ty_key) { switch (ty_key) {
@ -35,7 +38,7 @@ pub fn dotCompletions(
try completions.append(arena, .{ try completions.append(arena, .{
.label = error_name, .label = error_name,
.kind = .Constant, .kind = .Constant,
.detail = std.fmt.allocPrint(arena, "error.{s}", .{std.zig.fmtId(error_name)}), .detail = try std.fmt.allocPrint(arena, "error.{s}", .{std.zig.fmtId(error_name)}),
}); });
} }
}, },
@ -53,17 +56,17 @@ pub fn dotCompletions(
else => {}, else => {},
} }
}, },
else => false, else => {},
}, },
.pointer_type => |pointer_info| { .pointer_type => |pointer_info| {
if (pointer_info == .Slice) { if (pointer_info.size == .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_type.size = .Many; many_ptr_info.pointer_type.size = .Many;
try completions.append(arena, .{ try completions.append(arena, .{
.label = "ptr", .label = "ptr",
.kind = .Field, .kind = .Field,
.detail = std.fmt.allocPrint(arena, "{}", .{many_ptr_info.fmtType(ip)}), .detail = try std.fmt.allocPrint(arena, "{}", .{many_ptr_info.fmtType(ip.*)}),
}); });
try completions.append(arena, .{ try completions.append(arena, .{
.label = "len", .label = "len",
@ -81,9 +84,8 @@ pub fn dotCompletions(
.array_type => |array_info| { .array_type => |array_info| {
try completions.append(arena, types.CompletionItem{ try completions.append(arena, types.CompletionItem{
.label = "len", .label = "len",
.labelDetails = std.fmt.allocPrint(arena, "{d}", .{array_info.len}),
.kind = .Field, .kind = .Field,
.detail = "usize", .detail = try std.fmt.allocPrint(arena, "usize ({d})", .{array_info.len}), // TODO how should this be displayed
}); });
}, },
.struct_type => |struct_info| { .struct_type => |struct_info| {
@ -93,7 +95,7 @@ pub fn dotCompletions(
.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 = try std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip.*)}),
}); });
} }
}, },
@ -101,7 +103,7 @@ pub fn dotCompletions(
try completions.append(arena, .{ try completions.append(arena, .{
.label = "?", .label = "?",
.kind = .Operator, .kind = .Operator,
.detail = std.fmt.allocPrint(arena, "{}", .{optional_info.payload_type.fmtType(ip)}), .detail = try std.fmt.allocPrint(arena, "{}", .{optional_info.payload_type.fmtType(ip.*)}),
}); });
}, },
.enum_type => |enum_info| { .enum_type => |enum_info| {
@ -110,7 +112,7 @@ pub fn dotCompletions(
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 = try std.fmt.allocPrint(arena, "{}", .{field.val.fmtValue(enum_info.tag_type, ip.*)}),
}); });
} }
}, },
@ -121,22 +123,23 @@ pub fn dotCompletions(
.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) }) try std.fmt.allocPrint(arena, "align({d}) {}", .{ field.alignment, field.ty.fmtType(ip.*) })
else else
std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}), try std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip.*)}),
}); });
} }
}, },
.tuple_type => |tuple_info| { .tuple_type => |tuple_info| {
for (tuple_info.types) |tuple_ty,i| { for (tuple_info.types) |tuple_ty,i| {
try completions.append(arena, .{ try completions.append(arena, .{
.label = std.fmt.allocPrint(arena, "{d}", .{i}), .label = try std.fmt.allocPrint(arena, "{d}", .{i}),
.kind = .Field, .kind = .Field,
.detail = std.fmt.allocPrint(arena, "{}", .{tuple_ty.fmtType(ip)}), .detail = try std.fmt.allocPrint(arena, "{}", .{tuple_ty.fmtType(ip.*)}),
}); });
} }
}, },
.int_type, .int_type,
.error_set_type,
.error_union_type, .error_union_type,
.function_type, .function_type,
.vector_type, .vector_type,

View File

@ -787,7 +787,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
} }
return null; return null;
}; };
const val = result.getValue() catch |err| { const value = result.getValue() catch |err| {
log.err("Interpreter error: {s}", .{@errorName(err)}); log.err("Interpreter error: {s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*); std.debug.dumpStackTrace(trace.*);
@ -795,23 +795,16 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
return null; return null;
}; };
const type_type = try interpreter.ip.get(interpreter.allocator, ComptimeInterpreter.IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, ComptimeInterpreter.Key{ .simple = .type });
if (val.ty != type_type) { const is_type_val = value.ty == type_type;
log.err("Not a type: {}", .{val.ty.fmtType(interpreter.ip)});
return null;
}
return TypeWithHandle{ return TypeWithHandle{
.type = .{ .type = .{
.data = .{ .@"comptime" = .{ .data = .{ .@"comptime" = .{
.interpreter = interpreter, .interpreter = interpreter,
.type = ComptimeInterpreter.Type{ .value = value,
.interpreter = interpreter,
.node_idx = val.node_idx,
.ty = val.val,
},
} }, } },
.is_type_val = true, .is_type_val = is_type_val,
}, },
.handle = node_handle.handle, .handle = node_handle.handle,
}; };
@ -1064,7 +1057,7 @@ pub const Type = struct {
array_index, array_index,
@"comptime": struct { @"comptime": struct {
interpreter: *ComptimeInterpreter, interpreter: *ComptimeInterpreter,
type: ComptimeInterpreter.Type, value: ComptimeInterpreter.Value,
}, },
}, },
/// If true, the type `type`, the attached data is the value of the type value. /// If true, the type `type`, the attached data is the value of the type value.