From 829f4aa9c45521385af145dca8bf57816f5d8a64 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 23 Jan 2023 22:23:01 +0100 Subject: [PATCH] use `analyser/completions.zig` for completing comptime interpreter --- src/InternPool.zig | 3 +-- src/Server.zig | 23 ++++------------------- src/analyser/completions.zig | 31 +++++++++++++++++-------------- src/analysis.zig | 19 ++++++------------- 4 files changed, 28 insertions(+), 48 deletions(-) diff --git a/src/InternPool.zig b/src/InternPool.zig index fe94d20..0d7313c 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -31,8 +31,7 @@ pub const Pointer = packed struct { }; pub const Array = packed struct { - // TODO change to Index - len: u32, + len: u64, child: Index, sentinel: Index = .none, }; diff --git a/src/Server.zig b/src/Server.zig index ca71f60..876ae28 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -20,6 +20,7 @@ const tracy = @import("tracy.zig"); const uri_utils = @import("uri.zig"); const diff = @import("diff.zig"); const ComptimeInterpreter = @import("ComptimeInterpreter.zig"); +const analyser_completions = @import("analyser/completions.zig"); const data = @import("data/data.zig"); const snipped_data = @import("data/snippets.zig"); @@ -595,24 +596,8 @@ fn typeToCompletion( ), .primitive, .array_index => {}, .@"comptime" => |co| { - const key = co.interpreter.ip.indexToKey(co.type.ty); - - 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 => {}, - } + 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); }, } } @@ -934,7 +919,7 @@ fn hoverSymbol(server: *Server, decl_handle: analysis.DeclWithHandle) error{OutO const resolved_type_str = if (resolved_type) |rt| 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 switch (rt.type.data) { // TODO: Investigate random weird numbers like 897 that cause index of bounds .pointer, diff --git a/src/analyser/completions.zig b/src/analyser/completions.zig index 725e1da..1f74896 100644 --- a/src/analyser/completions.zig +++ b/src/analyser/completions.zig @@ -4,6 +4,8 @@ const types = @import("../lsp.zig"); const Ast = std.zig.Ast; + +/// TODO use std.ArrayListUnmanaged instead of returning a slice pub fn dotCompletions( arena: std.mem.Allocator, ip: *InternPool, @@ -25,7 +27,8 @@ pub fn dotCompletions( .simple => |simple| switch (simple) { .type => { const ty_key = ip.indexToKey(val); - if (ty_key.getNamespace()) { + const namespace = ty_key.getNamespace(); + if (namespace != .none) { // TODO lookup in namespace } switch (ty_key) { @@ -35,7 +38,7 @@ pub fn dotCompletions( try completions.append(arena, .{ .label = error_name, .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 => false, + else => {}, }, .pointer_type => |pointer_info| { - if (pointer_info == .Slice) { + if (pointer_info.size == .Slice) { var many_ptr_info = InternPool.Key{ .pointer_type = pointer_info }; many_ptr_info.pointer_type.size = .Many; try completions.append(arena, .{ .label = "ptr", .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, .{ .label = "len", @@ -81,9 +84,8 @@ pub fn dotCompletions( .array_type => |array_info| { try completions.append(arena, types.CompletionItem{ .label = "len", - .labelDetails = std.fmt.allocPrint(arena, "{d}", .{array_info.len}), .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| { @@ -93,7 +95,7 @@ pub fn dotCompletions( .label = field_name, .kind = .Field, // 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, .{ .label = "?", .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| { @@ -110,7 +112,7 @@ pub fn dotCompletions( try completions.append(arena, .{ .label = field_name, .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, .kind = .Field, .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 - std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip)}), + try std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip.*)}), }); } }, .tuple_type => |tuple_info| { for (tuple_info.types) |tuple_ty,i| { try completions.append(arena, .{ - .label = std.fmt.allocPrint(arena, "{d}", .{i}), + .label = try std.fmt.allocPrint(arena, "{d}", .{i}), .kind = .Field, - .detail = std.fmt.allocPrint(arena, "{}", .{tuple_ty.fmtType(ip)}), + .detail = try std.fmt.allocPrint(arena, "{}", .{tuple_ty.fmtType(ip.*)}), }); } }, .int_type, + .error_set_type, .error_union_type, .function_type, .vector_type, diff --git a/src/analysis.zig b/src/analysis.zig index f11f4c5..185342e 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -787,7 +787,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl } return null; }; - const val = result.getValue() catch |err| { + const value = result.getValue() catch |err| { log.err("Interpreter error: {s}", .{@errorName(err)}); if (@errorReturnTrace()) |trace| { std.debug.dumpStackTrace(trace.*); @@ -795,23 +795,16 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl return null; }; - const type_type = try interpreter.ip.get(interpreter.allocator, ComptimeInterpreter.IPKey{ .simple = .type }); - if (val.ty != type_type) { - log.err("Not a type: {}", .{val.ty.fmtType(interpreter.ip)}); - return null; - } + const type_type = try interpreter.ip.get(interpreter.allocator, ComptimeInterpreter.Key{ .simple = .type }); + const is_type_val = value.ty == type_type; return TypeWithHandle{ .type = .{ .data = .{ .@"comptime" = .{ .interpreter = interpreter, - .type = ComptimeInterpreter.Type{ - .interpreter = interpreter, - .node_idx = val.node_idx, - .ty = val.val, - }, + .value = value, } }, - .is_type_val = true, + .is_type_val = is_type_val, }, .handle = node_handle.handle, }; @@ -1064,7 +1057,7 @@ pub const Type = struct { array_index, @"comptime": struct { interpreter: *ComptimeInterpreter, - type: ComptimeInterpreter.Type, + value: ComptimeInterpreter.Value, }, }, /// If true, the type `type`, the attached data is the value of the type value.