Skip to content

Commit

Permalink
resolve vector types (#1799)
Browse files Browse the repository at this point in the history
  • Loading branch information
Techatrix authored Feb 29, 2024
1 parent a4c13e6 commit 7d6a9e2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
57 changes: 43 additions & 14 deletions src/analysis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,21 @@ fn allDigits(str: []const u8) bool {
return true;
}

fn resolveIntegerLiteral(analyser: *Analyser, node_handle: NodeWithHandle) !?u64 {
// When resolve_number_literal_values is set then resolveTypeOfNode will also resolve the value of number literals.
// So we can use it to resolve integer values.

const old_resolve_number_literal_values = analyser.resolve_number_literal_values;
analyser.resolve_number_literal_values = true;
defer analyser.resolve_number_literal_values = old_resolve_number_literal_values;

const resolved_length = try analyser.resolveTypeOfNode(node_handle) orelse return null;
switch (resolved_length.data) {
.ip_index => |payload| return analyser.ip.toInt(payload.index, u64),
else => return null,
}
}

const primitives = std.ComptimeStringMap(InternPool.Index, .{
.{ "anyerror", .anyerror_type },
.{ "anyframe", .anyframe_type },
Expand Down Expand Up @@ -1491,20 +1506,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
=> {
const array_info = tree.fullArrayType(node).?;

const elem_count: ?u64 = blk: {
// When resolve_number_literal_values is set then resolveTypeOfNode will also resolve the value of number literals.
// So we can use it to resolve the element count.

const old_resolve_number_literal_values = analyser.resolve_number_literal_values;
analyser.resolve_number_literal_values = true;
defer analyser.resolve_number_literal_values = old_resolve_number_literal_values;

const resolved_elem_count = try analyser.resolveTypeOfNode(.{ .node = array_info.ast.elem_count, .handle = handle }) orelse break :blk null;
switch (resolved_elem_count.data) {
.ip_index => |payload| break :blk analyser.ip.toInt(payload.index, u64),
else => break :blk null,
}
};
const elem_count: ?u64 = try analyser.resolveIntegerLiteral(.{ .node = array_info.ast.elem_count, .handle = handle });

const sentinel: InternPool.Index = if (array_info.ast.sentinel != 0) blk: {
// resolveTypeOfNode can also resolve values that returned as indices into the InternPool.
Expand Down Expand Up @@ -1739,6 +1741,33 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
if (std.mem.eql(u8, call_name, "@compileError")) {
return Type{ .data = .{ .compile_error = node_handle }, .is_type_val = false };
}

if (std.mem.eql(u8, call_name, "@Vector")) {
if (params.len != 2) return null;

const child_ty = try analyser.resolveTypeOfNodeInternal(.{ .node = params[1], .handle = handle }) orelse return null;
if (!child_ty.is_type_val) return null;

const child_ty_ip_index = switch (child_ty.data) {
.ip_index => |payload| payload.index,
else => return null,
};

const len: u64 = try analyser.resolveIntegerLiteral(.{ .node = params[0], .handle = handle }) orelse
return null; // `InternPool.Key.Vector.len` can't represent unknown length yet

const vector_ty_ip_index = try analyser.ip.get(analyser.gpa, .{
.vector_type = .{
.len = std.math.cast(u32, len) orelse return null,
.child = child_ty_ip_index,
},
});

return Type{
.data = .{ .ip_index = .{ .index = vector_ty_ip_index } },
.is_type_val = true,
};
}
},
.fn_proto,
.fn_proto_multi,
Expand Down
13 changes: 13 additions & 0 deletions tests/lsp_features/hover.zig
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ test "builtin" {
, .{ .markup_kind = .plaintext });
}

test "vector type" {
try testHover(
\\const u32<cursor>x4: @Vector(4, u32) = undefined;
,
\\```zig
\\const u32x4: @Vector(4, u32) = undefined
\\```
\\```zig
\\(@Vector(4,u32))
\\```
);
}

test "negation" {
try testHover(
\\const f<cursor>oo = 1;
Expand Down

0 comments on commit 7d6a9e2

Please sign in to comment.