diff --git a/src/analysis.zig b/src/analysis.zig index 4ae8b9f..2c8cbbe 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -494,7 +494,7 @@ fn resolveUnwrapErrorType(store: *DocumentStore, arena: *std.heap.ArenaAllocator .type = .{ .data = .{ .other = n }, .is_type_val = rhs.type.is_type_val }, .handle = rhs.handle, }, - .primitive, .slice, .pointer => return null, + .primitive, .slice, .pointer, .array_index => return null, }; if (rhs.handle.tree.nodes.items(.tag)[rhs_node] == .error_union) { @@ -670,7 +670,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl .identifier => { if (isTypeIdent(handle.tree, main_tokens[node])) { return TypeWithHandle{ - .type = .{ .data = .primitive, .is_type_val = true }, + .type = .{ .data = .{ .primitive = node }, .is_type_val = true }, .handle = handle, }; } @@ -977,7 +977,8 @@ pub const Type = struct { slice: Ast.Node.Index, error_union: Ast.Node.Index, other: Ast.Node.Index, - primitive, + primitive: Ast.Node.Index, + array_index, }, /// If true, the type `type`, the attached data is the value of the type value. is_type_val: bool, @@ -1941,7 +1942,7 @@ pub const DeclWithHandle = struct { bound_type_params, ), .array_index => TypeWithHandle{ - .type = .{ .data = .primitive, .is_type_val = false }, + .type = .{ .data = .array_index, .is_type_val = false }, .handle = self.handle, }, .label_decl => return null, diff --git a/src/main.zig b/src/main.zig index ef5c6b4..f4cc653 100644 --- a/src/main.zig +++ b/src/main.zig @@ -404,7 +404,7 @@ fn typeToCompletion( null, config, ), - .primitive => {}, + .primitive, .array_index => {}, } } @@ -736,19 +736,50 @@ fn hoverSymbol(id: types.RequestId, arena: *std.heap.ArenaAllocator, decl_handle .label_decl => |label_decl| tree.tokenSlice(label_decl), }; + var bound_type_params = analysis.BoundTypeParams.init(arena.allocator()); + const resolved_type = try decl_handle.resolveType(&document_store, arena, &bound_type_params); + + const resolved_type_str = if (resolved_type) |rt| + if (rt.type.is_type_val) "type" else switch (rt.type.data) { + .pointer, + .slice, + .error_union, + .primitive, + => |p| tree.getNodeSource(p), + .other => |p| switch (tree.nodes.items(.tag)[p]) { + .container_decl, + .container_decl_arg, + .container_decl_arg_trailing, + .container_decl_trailing, + .container_decl_two, + .container_decl_two_trailing, + .tagged_union, + .tagged_union_trailing, + .tagged_union_two, + .tagged_union_two_trailing, + .tagged_union_enum_tag, + .tagged_union_enum_tag_trailing, + => tree.tokenSlice(tree.nodes.items(.main_token)[p] - 2), // NOTE: This is a hacky nightmare but it works :P + else => tree.getNodeSource(p), + }, + else => "unknown", + } + else + "unknown"; + var hover_text: []const u8 = undefined; if (hover_kind == .Markdown) { hover_text = if (doc_str) |doc| - try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```\n{s}", .{ def_str, doc }) + try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```\n```zig\n({s})\n```\n{s}", .{ def_str, resolved_type_str, doc }) else - try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```", .{def_str}); + try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```\n```zig\n({s})\n```", .{ def_str, resolved_type_str }); } else { hover_text = if (doc_str) |doc| - try std.fmt.allocPrint(arena.allocator(), "{s}\n{s}", .{ def_str, doc }) + try std.fmt.allocPrint(arena.allocator(), "{s} ({s})\n{s}", .{ def_str, resolved_type_str, doc }) else - def_str; + try std.fmt.allocPrint(arena.allocator(), "{s} ({s})", .{ def_str, resolved_type_str }); } try send(arena, types.Response{