vtables, protocol

This commit is contained in:
agra
2026-02-24 06:20:38 +02:00
parent 0cc7b69441
commit 170e236764
16 changed files with 3032 additions and 294 deletions

View File

@@ -399,6 +399,7 @@ pub const Server = struct {
.constant => @intFromEnum(lsp.SymbolKindLsp.Constant),
.enum_type => @intFromEnum(lsp.SymbolKindLsp.Enum),
.struct_type => @intFromEnum(lsp.SymbolKindLsp.Struct),
.protocol_type => @intFromEnum(lsp.SymbolKindLsp.Interface),
.type_alias => @intFromEnum(lsp.SymbolKindLsp.Class),
.param => @intFromEnum(lsp.SymbolKindLsp.Variable),
.namespace => @intFromEnum(lsp.SymbolKindLsp.Namespace),
@@ -455,6 +456,7 @@ pub const Server = struct {
.constant => @intFromEnum(lsp.CompletionItemKind.Constant),
.enum_type => @intFromEnum(lsp.CompletionItemKind.Enum),
.struct_type => @intFromEnum(lsp.CompletionItemKind.Struct),
.protocol_type => @intFromEnum(lsp.CompletionItemKind.Interface),
.type_alias => @intFromEnum(lsp.CompletionItemKind.Class),
.param => @intFromEnum(lsp.CompletionItemKind.Variable),
.namespace => @intFromEnum(lsp.CompletionItemKind.Module),
@@ -790,11 +792,13 @@ pub const Server = struct {
for (fd.params, 0..) |param, pi| {
if (pi > 0) try detail_buf.appendSlice(allocator, ", ");
try detail_buf.appendSlice(allocator, param.name);
try detail_buf.appendSlice(allocator, ": ");
if (param.type_expr.data == .type_expr) {
try detail_buf.appendSlice(allocator, param.type_expr.data.type_expr.name);
} else {
try detail_buf.appendSlice(allocator, "?");
if (param.type_expr.data != .inferred_type) {
try detail_buf.appendSlice(allocator, ": ");
if (param.type_expr.data == .type_expr) {
try detail_buf.appendSlice(allocator, param.type_expr.data.type_expr.name);
} else {
try detail_buf.appendSlice(allocator, "?");
}
}
}
try detail_buf.append(allocator, ')');
@@ -838,6 +842,12 @@ pub const Server = struct {
.kind = @intFromEnum(lsp.CompletionItemKind.Struct),
});
},
.protocol_decl => |pd| {
try items.append(allocator, .{
.label = pd.name,
.kind = @intFromEnum(lsp.CompletionItemKind.Interface),
});
},
.var_decl => |vd| {
try items.append(allocator, .{
.label = vd.name,
@@ -892,6 +902,43 @@ pub const Server = struct {
}
}
}
} else if (sym.kind == .protocol_type) {
const lookup_root = if (sym.origin) |origin_path|
if (self.documents.get(origin_path)) |od| od.root orelse root else root
else
root;
if (sx.sema.findNodeAtOffset(lookup_root, sym.def_span.start)) |node| {
if (node.data == .protocol_decl) {
const pd = node.data.protocol_decl;
for (pd.methods) |method| {
// Build detail string: (params) -> ret
var detail_buf = std.ArrayList(u8).empty;
try detail_buf.append(self.allocator, '(');
for (method.param_names, 0..) |pname, pi| {
if (pi > 0) try detail_buf.appendSlice(self.allocator, ", ");
try detail_buf.appendSlice(self.allocator, pname);
if (pi < method.params.len) {
try detail_buf.appendSlice(self.allocator, ": ");
if (method.params[pi].data == .type_expr) {
try detail_buf.appendSlice(self.allocator, method.params[pi].data.type_expr.name);
}
}
}
try detail_buf.append(self.allocator, ')');
if (method.return_type) |rt| {
try detail_buf.appendSlice(self.allocator, " -> ");
if (rt.data == .type_expr) {
try detail_buf.appendSlice(self.allocator, rt.data.type_expr.name);
}
}
try items.append(self.allocator, .{
.label = method.name,
.kind = @intFromEnum(lsp.CompletionItemKind.Method),
.detail = detail_buf.items,
});
}
}
}
}
break;
}
@@ -956,11 +1003,13 @@ pub const Server = struct {
if (pi > 0) try label_buf.appendSlice(self.allocator, ", ");
const param_start = label_buf.items.len;
try label_buf.appendSlice(self.allocator, param.name);
try label_buf.appendSlice(self.allocator, ": ");
if (param.type_expr.data == .type_expr) {
try label_buf.appendSlice(self.allocator, param.type_expr.data.type_expr.name);
} else {
try label_buf.appendSlice(self.allocator, "?");
if (param.type_expr.data != .inferred_type) {
try label_buf.appendSlice(self.allocator, ": ");
if (param.type_expr.data == .type_expr) {
try label_buf.appendSlice(self.allocator, param.type_expr.data.type_expr.name);
} else {
try label_buf.appendSlice(self.allocator, "?");
}
}
const param_label = try self.allocator.dupe(u8, label_buf.items[param_start..]);
try param_labels.append(self.allocator, param_label);
@@ -1361,6 +1410,9 @@ pub const Server = struct {
.kw_push,
.kw_ufcs,
.kw_in,
.kw_closure,
.kw_protocol,
.kw_impl,
.hash_run,
.hash_import,
.hash_insert,
@@ -1372,9 +1424,10 @@ pub const Server = struct {
.hash_source,
.hash_define,
.hash_flags,
.hash_inline,
=> ST.keyword,
.kw_f32, .kw_f64, .kw_Type => ST.type_,
.kw_f32, .kw_f64, .kw_Type, .kw_Self => ST.type_,
.int_literal, .float_literal => ST.number,
.string_literal, .raw_string_literal => null,
@@ -1480,6 +1533,7 @@ pub const Server = struct {
.param => ST.parameter,
.enum_type => ST.enum_,
.struct_type => ST.struct_,
.protocol_type => ST.interface,
.type_alias => ST.type_,
.namespace => ST.namespace,
};
@@ -1817,8 +1871,10 @@ pub const Server = struct {
for (params, 0..) |param, pi| {
if (pi > 0) try buf.appendSlice(self.allocator, ", ");
try buf.appendSlice(self.allocator, param.name);
try buf.appendSlice(self.allocator, ": ");
if (param.type_expr.data == .type_expr) {
if (param.type_expr.data == .inferred_type) {
// Inferred type — show name only
} else if (param.type_expr.data == .type_expr) {
try buf.appendSlice(self.allocator, ": ");
try buf.appendSlice(self.allocator, param.type_expr.data.type_expr.name);
} else {
try buf.appendSlice(self.allocator, "?");
@@ -2305,11 +2361,13 @@ pub const Server = struct {
for (fd.params, 0..) |param, pi| {
if (pi > 0) try buf.appendSlice(allocator, ", ");
try buf.appendSlice(allocator, param.name);
try buf.appendSlice(allocator, ": ");
if (param.type_expr.data == .type_expr) {
try buf.appendSlice(allocator, param.type_expr.data.type_expr.name);
} else {
try buf.appendSlice(allocator, "?");
if (param.type_expr.data != .inferred_type) {
try buf.appendSlice(allocator, ": ");
if (param.type_expr.data == .type_expr) {
try buf.appendSlice(allocator, param.type_expr.data.type_expr.name);
} else {
try buf.appendSlice(allocator, "?");
}
}
}
try buf.append(allocator, ')');
@@ -2407,6 +2465,44 @@ pub const Server = struct {
}
try buf.appendSlice(allocator, " }");
},
.protocol_decl => |pd| {
try buf.appendSlice(allocator, pd.name);
try buf.appendSlice(allocator, " :: protocol");
if (pd.is_inline) try buf.appendSlice(allocator, " #inline");
try buf.appendSlice(allocator, " { ");
for (pd.methods, 0..) |method, mi| {
if (mi > 0) try buf.appendSlice(allocator, " ");
try buf.appendSlice(allocator, method.name);
try buf.appendSlice(allocator, " :: (");
for (method.param_names, 0..) |pname, pi| {
if (pi > 0) try buf.appendSlice(allocator, ", ");
try buf.appendSlice(allocator, pname);
if (pi < method.params.len) {
try buf.appendSlice(allocator, ": ");
if (method.params[pi].data == .type_expr) {
try buf.appendSlice(allocator, method.params[pi].data.type_expr.name);
} else {
try buf.appendSlice(allocator, "?");
}
}
}
try buf.append(allocator, ')');
if (method.return_type) |rt| {
try buf.appendSlice(allocator, " -> ");
if (rt.data == .type_expr) {
try buf.appendSlice(allocator, rt.data.type_expr.name);
}
}
try buf.appendSlice(allocator, ";");
}
try buf.appendSlice(allocator, " }");
},
.impl_block => |ib| {
try buf.appendSlice(allocator, "impl ");
try buf.appendSlice(allocator, ib.protocol_name);
try buf.appendSlice(allocator, " for ");
try buf.appendSlice(allocator, ib.target_type);
},
.const_decl => |cd| {
try buf.appendSlice(allocator, cd.name);
try buf.appendSlice(allocator, " :: ");
@@ -2507,6 +2603,10 @@ pub const Server = struct {
try buf.appendSlice(allocator, sym.name);
try buf.appendSlice(allocator, " :: struct { ... }");
},
.protocol_type => {
try buf.appendSlice(allocator, sym.name);
try buf.appendSlice(allocator, " :: protocol { ... }");
},
.type_alias => {
try buf.appendSlice(allocator, sym.name);
try buf.appendSlice(allocator, " :: (type)");