refactor type printing
This commit is contained in:
parent
739bd08b7b
commit
407f921ef8
@ -256,7 +256,7 @@ pub fn interpret(
|
|||||||
try interpreter.recordError(
|
try interpreter.recordError(
|
||||||
container_field.ast.type_expr,
|
container_field.ast.type_expr,
|
||||||
"expected_type",
|
"expected_type",
|
||||||
try std.fmt.allocPrint(interpreter.allocator, "expected type 'type', found '{}'", .{init_type_value.ty.fmtType(&interpreter.ip)}),
|
try std.fmt.allocPrint(interpreter.allocator, "expected type 'type', found '{}'", .{init_type_value.ty.fmtType(interpreter.ip)}),
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ pub fn interpret(
|
|||||||
try writer.writeAll("indeterminate");
|
try writer.writeAll("indeterminate");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
try writer.print("@as({}, {})", .{ value.ty.fmtType(&interpreter.ip), value.val.fmtValue(value.ty, &interpreter.ip) });
|
try writer.print("@as({}, {})", .{ value.ty.fmtType(interpreter.ip), value.val.fmtValue(value.ty, interpreter.ip) });
|
||||||
if (index != params.len - 1)
|
if (index != params.len - 1)
|
||||||
try writer.writeAll(", ");
|
try writer.writeAll(", ");
|
||||||
}
|
}
|
||||||
@ -981,7 +981,7 @@ pub fn call(
|
|||||||
try interpreter.recordError(
|
try interpreter.recordError(
|
||||||
param.type_expr,
|
param.type_expr,
|
||||||
"expected_type",
|
"expected_type",
|
||||||
std.fmt.allocPrint(interpreter.allocator, "expected type 'type', found '{}'", .{tex.ty.fmtType(&interpreter.ip)}) catch return error.CriticalAstFailure,
|
std.fmt.allocPrint(interpreter.allocator, "expected type 'type', found '{}'", .{tex.ty.fmtType(interpreter.ip)}) catch return error.CriticalAstFailure,
|
||||||
);
|
);
|
||||||
return error.InvalidCast;
|
return error.InvalidCast;
|
||||||
}
|
}
|
||||||
|
@ -419,16 +419,17 @@ pub const Key = union(enum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const TypeFormatContext = struct {
|
pub const TypeFormatContext = struct {
|
||||||
ty: Index,
|
ty: Key,
|
||||||
options: FormatOptions = .{},
|
options: FormatOptions = .{},
|
||||||
ip: *const InternPool,
|
ip: InternPool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ValueFormatContext = struct {
|
pub const ValueFormatContext = struct {
|
||||||
value: Index,
|
value: Key,
|
||||||
|
/// for most values the type is not needed which is why we use an index
|
||||||
ty: Index,
|
ty: Index,
|
||||||
options: FormatOptions = .{},
|
options: FormatOptions = .{},
|
||||||
ip: *const InternPool,
|
ip: InternPool,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO implement options
|
// TODO implement options
|
||||||
@ -437,20 +438,30 @@ pub const Key = union(enum) {
|
|||||||
include_declarations: bool = true,
|
include_declarations: bool = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn formatType(
|
fn formatType(
|
||||||
ctx: TypeFormatContext,
|
ctx: TypeFormatContext,
|
||||||
comptime unused_format_string: []const u8,
|
comptime fmt: []const u8,
|
||||||
options: std.fmt.FormatOptions,
|
options: std.fmt.FormatOptions,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
) @TypeOf(writer).Error!void {
|
) @TypeOf(writer).Error!void {
|
||||||
comptime assert(unused_format_string.len == 0);
|
|
||||||
_ = options;
|
_ = options;
|
||||||
return printType(ctx.ty, ctx.ip, writer);
|
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, Key);
|
||||||
|
try printTypeKey(ctx.ty, ctx.ip, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn printType(ty: Index, ip: *const InternPool, writer: anytype) @TypeOf(writer).Error!void {
|
fn printType(ty: Index, ip: InternPool, writer: anytype) @TypeOf(writer).Error!void {
|
||||||
const key: Key = ip.indexToKey(ty);
|
try printTypeKey(ip.indexToKey(ty), ip, writer);
|
||||||
switch (key) {
|
}
|
||||||
|
|
||||||
|
fn printTypeKey(ty: Key, ip: InternPool, writer: anytype) @TypeOf(writer).Error!void {
|
||||||
|
var key = ty;
|
||||||
|
while (try printTypeInternal(key, ip, writer)) |index| {
|
||||||
|
key = ip.indexToKey(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printTypeInternal(ty: Key, ip: InternPool, writer: anytype) @TypeOf(writer).Error!?Index {
|
||||||
|
switch (ty) {
|
||||||
.simple => |simple| switch (simple) {
|
.simple => |simple| switch (simple) {
|
||||||
.f16,
|
.f16,
|
||||||
.f32,
|
.f32,
|
||||||
@ -527,7 +538,7 @@ pub const Key = union(enum) {
|
|||||||
if (pointer_info.is_volatile) try writer.writeAll("volatile ");
|
if (pointer_info.is_volatile) try writer.writeAll("volatile ");
|
||||||
if (pointer_info.is_allowzero and pointer_info.size != .C) try writer.writeAll("allowzero ");
|
if (pointer_info.is_allowzero and pointer_info.size != .C) try writer.writeAll("allowzero ");
|
||||||
|
|
||||||
try printType(pointer_info.elem_type, ip, writer);
|
return pointer_info.elem_type;
|
||||||
},
|
},
|
||||||
.array_type => |array_info| {
|
.array_type => |array_info| {
|
||||||
try writer.print("[{d}", .{array_info.len});
|
try writer.print("[{d}", .{array_info.len});
|
||||||
@ -535,18 +546,18 @@ pub const Key = union(enum) {
|
|||||||
try writer.print(":{}", .{array_info.sentinel.fmtValue(array_info.child, ip)});
|
try writer.print(":{}", .{array_info.sentinel.fmtValue(array_info.child, ip)});
|
||||||
}
|
}
|
||||||
try writer.writeByte(']');
|
try writer.writeByte(']');
|
||||||
try printType(array_info.child, ip, writer);
|
|
||||||
|
return array_info.child;
|
||||||
},
|
},
|
||||||
.struct_type => @panic("TODO"),
|
.struct_type => @panic("TODO"),
|
||||||
.optional_type => |optional_info| {
|
.optional_type => |optional_info| {
|
||||||
try writer.writeByte('?');
|
try writer.writeByte('?');
|
||||||
try printType(optional_info.payload_type, ip, writer);
|
return optional_info.payload_type;
|
||||||
},
|
},
|
||||||
.error_union_type => |error_union_info| {
|
.error_union_type => |error_union_info| {
|
||||||
try writer.print("{}!{}", .{
|
try printType(error_union_info.error_set_type, ip, writer);
|
||||||
error_union_info.error_set_type.fmtType(ip),
|
try writer.writeByte('!');
|
||||||
error_union_info.payload_type.fmtType(ip),
|
return error_union_info.payload_type;
|
||||||
});
|
|
||||||
},
|
},
|
||||||
.error_set_type => |error_set_info| {
|
.error_set_type => |error_set_info| {
|
||||||
const names = error_set_info.names;
|
const names = error_set_info.names;
|
||||||
@ -585,10 +596,8 @@ pub const Key = union(enum) {
|
|||||||
if (function_info.calling_convention != .Unspecified) {
|
if (function_info.calling_convention != .Unspecified) {
|
||||||
try writer.print("callconv(.{s}) ", .{@tagName(function_info.calling_convention)});
|
try writer.print("callconv(.{s}) ", .{@tagName(function_info.calling_convention)});
|
||||||
}
|
}
|
||||||
if (function_info.alignment != 0) {
|
|
||||||
try writer.print("align({d}) ", .{function_info.alignment});
|
return function_info.return_type;
|
||||||
}
|
|
||||||
try printType(function_info.return_type, ip, writer);
|
|
||||||
},
|
},
|
||||||
.union_type => @panic("TODO"),
|
.union_type => @panic("TODO"),
|
||||||
.tuple_type => |tuple_info| {
|
.tuple_type => |tuple_info| {
|
||||||
@ -614,7 +623,7 @@ pub const Key = union(enum) {
|
|||||||
},
|
},
|
||||||
.anyframe_type => |anyframe_info| {
|
.anyframe_type => |anyframe_info| {
|
||||||
try writer.writeAll("anyframe->");
|
try writer.writeAll("anyframe->");
|
||||||
try printType(anyframe_info.child, ip, writer);
|
return anyframe_info.child;
|
||||||
},
|
},
|
||||||
|
|
||||||
.int_u64_value,
|
.int_u64_value,
|
||||||
@ -632,27 +641,28 @@ pub const Key = union(enum) {
|
|||||||
.union_value,
|
.union_value,
|
||||||
=> unreachable,
|
=> unreachable,
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn formatValue(
|
fn formatValue(
|
||||||
ctx: ValueFormatContext,
|
ctx: ValueFormatContext,
|
||||||
comptime unused_format_string: []const u8,
|
comptime fmt: []const u8,
|
||||||
options: std.fmt.FormatOptions,
|
options: std.fmt.FormatOptions,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
) @TypeOf(writer).Error!void {
|
) @TypeOf(writer).Error!void {
|
||||||
comptime assert(unused_format_string.len == 0);
|
comptime assert(fmt.len == 0);
|
||||||
_ = options;
|
_ = options;
|
||||||
|
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, Key);
|
||||||
return printValue(ctx.value, ctx.ty, ctx.ip, writer);
|
return printValue(ctx.value, ctx.ty, ctx.ip, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn printValue(
|
fn printValue(
|
||||||
value: Index,
|
value: Key,
|
||||||
ty: Index,
|
ty: Index,
|
||||||
ip: *const InternPool,
|
ip: InternPool,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
) @TypeOf(writer).Error!void {
|
) @TypeOf(writer).Error!void {
|
||||||
const value_key: Key = ip.indexToKey(value);
|
switch (value) {
|
||||||
switch (value_key) {
|
|
||||||
.simple => |simple| switch (simple) {
|
.simple => |simple| switch (simple) {
|
||||||
.f16,
|
.f16,
|
||||||
.f32,
|
.f32,
|
||||||
@ -729,7 +739,7 @@ pub const Key = union(enum) {
|
|||||||
if (i != 0) try writer.writeAll(", ");
|
if (i != 0) try writer.writeAll(", ");
|
||||||
|
|
||||||
try writer.print(".{s} = ", .{struct_info.fields[i].name});
|
try writer.print(".{s} = ", .{struct_info.fields[i].name});
|
||||||
try printValue(aggregate[i], struct_info.fields[i].ty, ip, writer);
|
try printValue(ip.indexToKey(aggregate[i]), struct_info.fields[i].ty, ip, writer);
|
||||||
}
|
}
|
||||||
try writer.writeByte('}');
|
try writer.writeByte('}');
|
||||||
},
|
},
|
||||||
@ -737,13 +747,28 @@ pub const Key = union(enum) {
|
|||||||
const union_info = ip.indexToKey(ty).union_type;
|
const union_info = ip.indexToKey(ty).union_type;
|
||||||
|
|
||||||
try writer.writeAll(".{ ");
|
try writer.writeAll(".{ ");
|
||||||
try printValue(union_info.tag_type, union_value.tag, ip, writer);
|
try printValue(ip.indexToKey(union_info.tag_type), union_value.tag, ip, writer);
|
||||||
try writer.writeAll(" = ");
|
try writer.writeAll(" = ");
|
||||||
try printValue(union_value.val, @panic("TODO"), ip, writer);
|
try printValue(union_value.val, @panic("TODO"), ip, writer);
|
||||||
try writer.writeAll(" }");
|
try writer.writeAll(" }");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fmtType(ty: Key, ip: InternPool) std.fmt.Formatter(formatType) {
|
||||||
|
return .{ .data = .{
|
||||||
|
.ty = ty,
|
||||||
|
.ip = ip,
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fmtValue(value: Key, ty: Index, ip: InternPool) std.fmt.Formatter(formatValue) {
|
||||||
|
return .{ .data = .{
|
||||||
|
.value = value,
|
||||||
|
.ty = ty,
|
||||||
|
.ip = ip,
|
||||||
|
} };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Item = struct {
|
pub const Item = struct {
|
||||||
@ -761,16 +786,16 @@ pub const Index = enum(u32) {
|
|||||||
none = std.math.maxInt(u32),
|
none = std.math.maxInt(u32),
|
||||||
_,
|
_,
|
||||||
|
|
||||||
pub fn fmtType(ty: Index, ip: *const InternPool) std.fmt.Formatter(Key.formatType) {
|
pub fn fmtType(ty: Index, ip: InternPool) std.fmt.Formatter(Key.formatType) {
|
||||||
return .{ .data = .{
|
return .{ .data = .{
|
||||||
.ty = ty,
|
.ty = ip.indexToKey(ty),
|
||||||
.ip = ip,
|
.ip = ip,
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmtValue(value_index: Index, type_index: Index, ip: *const InternPool) std.fmt.Formatter(Key.formatValue) {
|
pub fn fmtValue(value_index: Index, type_index: Index, ip: InternPool) std.fmt.Formatter(Key.formatValue) {
|
||||||
return .{ .data = .{
|
return .{ .data = .{
|
||||||
.value = value_index,
|
.value = ip.indexToKey(value_index),
|
||||||
.ty = type_index,
|
.ty = type_index,
|
||||||
.ip = ip,
|
.ip = ip,
|
||||||
} };
|
} };
|
||||||
|
@ -583,7 +583,7 @@ fn typeToCompletion(
|
|||||||
.primitive, .array_index => {},
|
.primitive, .array_index => {},
|
||||||
.@"comptime" => |co| {
|
.@"comptime" => |co| {
|
||||||
const key = co.interpreter.ip.indexToKey(co.type.ty);
|
const key = co.interpreter.ip.indexToKey(co.type.ty);
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
.struct_type => |struct_info| {
|
.struct_type => |struct_info| {
|
||||||
for (struct_info.fields) |field| {
|
for (struct_info.fields) |field| {
|
||||||
@ -594,7 +594,7 @@ fn typeToCompletion(
|
|||||||
.insertTextFormat = .PlainText,
|
.insertTextFormat = .PlainText,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO declaration completion
|
// TODO declaration completion
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
@ -916,7 +916,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.type.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,
|
||||||
|
@ -793,7 +793,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
|
|||||||
|
|
||||||
const type_type = try interpreter.ip.get(interpreter.allocator, ComptimeInterpreter.IPKey{ .simple = .type });
|
const type_type = try interpreter.ip.get(interpreter.allocator, ComptimeInterpreter.IPKey{ .simple = .type });
|
||||||
if (val.ty != type_type) {
|
if (val.ty != type_type) {
|
||||||
log.err("Not a type: {}", .{val.ty.fmtType(&interpreter.ip)});
|
log.err("Not a type: {}", .{val.ty.fmtType(interpreter.ip)});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user