Skip to content

Commit

Permalink
resolved array length when possible, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
estevesnp committed Jan 4, 2025
1 parent f13da7a commit c262205
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 10 deletions.
47 changes: 37 additions & 10 deletions src/analysis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,17 @@ fn resolveIntegerLiteral(analyser: *Analyser, comptime T: type, node_handle: Nod
return analyser.ip.toInt(ip_index, T);
}

fn extractArrayData(data: *Type.Data) ?*Type.Data {
return switch (data.*) {
.array => data,
.pointer => |*p| switch (p.elem_ty.data) {
.array => &p.elem_ty.data,
else => null,
},
else => null,
};
}

const primitives: std.StaticStringMap(InternPool.Index) = .initComptime(.{
.{ "anyerror", .anyerror_type },
.{ "anyframe", .anyframe_type },
Expand Down Expand Up @@ -2256,24 +2267,40 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
=> {},

.array_mult,
.array_cat,
=> {
const elem_idx = datas[node].lhs;
var elem_ty = try analyser.resolveTypeOfNodeInternal(.{ .node = elem_idx, .handle = handle }) orelse return null;
const arr_data = extractArrayData(&elem_ty.data) orelse return null;

switch (elem_ty.data) {
.array => |*a| a.elem_count = null,
.pointer => |*p| {
switch (p.elem_ty.data) {
.array => |*a| a.elem_count = null,
else => return null,
}
},
else => return null,
const mult_idx = datas[node].rhs;
const mult_lit = try analyser.resolveIntegerLiteral(u64, .{ .node = mult_idx, .handle = handle });

if (arr_data.array.elem_count) |count| {
arr_data.array.elem_count = if (mult_lit) |mult| count * mult else null;
}

return elem_ty;
},
.array_cat,
=> {
const l_elem_idx = datas[node].lhs;
var l_elem_ty = try analyser.resolveTypeOfNodeInternal(.{ .node = l_elem_idx, .handle = handle }) orelse return null;
const l_arr_data = extractArrayData(&l_elem_ty.data) orelse return null;

const r_elem_idx = datas[node].rhs;
var r_elem_ty = try analyser.resolveTypeOfNodeInternal(.{ .node = r_elem_idx, .handle = handle }) orelse return null;
const r_arr_data = extractArrayData(&r_elem_ty.data) orelse return null;

if (l_arr_data.array.elem_count != null) {
if (r_arr_data.array.elem_count) |right_count| {
l_arr_data.array.elem_count.? += right_count;
} else {
l_arr_data.array.elem_count = null;
}
}

return l_elem_ty;
},

.assign_mul,
.assign_div,
Expand Down
83 changes: 83 additions & 0 deletions tests/lsp_features/hover.zig
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,89 @@ test "union" {
);
}

test "array cat and mult" {
try testHover(
\\const <cursor>a = [_]u8{0} ++ [_]u8{1};
,
\\```zig
\\const a = [_]u8{0} ++ [_]u8{1}
\\```
\\```zig
\\([?]u8)
\\```
);
try testHover(
\\const <cursor>a = [1]u8{0} ++ [_]u8{1};
,
\\```zig
\\const a = [1]u8{0} ++ [_]u8{1}
\\```
\\```zig
\\([?]u8)
\\```
);
try testHover(
\\const <cursor>a = [_]u8{0} ++ [1]u8{1};
,
\\```zig
\\const a = [_]u8{0} ++ [1]u8{1}
\\```
\\```zig
\\([?]u8)
\\```
);
try testHover(
\\const <cursor>a = [1]u8{0} ++ [1]u8{1};
,
\\```zig
\\const a = [1]u8{0} ++ [1]u8{1}
\\```
\\```zig
\\([2]u8)
\\```
);
try testHover(
\\const <cursor>a = &[2]u8{ 0, 1 } ++ &[3]u8{ 2, 3, 4 };
,
\\```zig
\\const a = &[2]u8{ 0, 1 } ++ &[3]u8{ 2, 3, 4 }
\\```
\\```zig
\\(*[5]u8)
\\```
);
try testHover(
\\const <cursor>a = [_]u8{0} ** 2;
,
\\```zig
\\const a = [_]u8{0} ** 2
\\```
\\```zig
\\([?]u8)
\\```
);
try testHover(
\\const <cursor>a = [1]u8{0} ** 2;
,
\\```zig
\\const a = [1]u8{0} ** 2
\\```
\\```zig
\\([2]u8)
\\```
);
try testHover(
\\const <cursor>a = &[3]u8{ 0, 1, 2 } ** 2;
,
\\```zig
\\const a = &[3]u8{ 0, 1, 2 } ** 2
\\```
\\```zig
\\(*[6]u8)
\\```
);
}

test "sentinel values" {
try testHover(
\\const <cursor>a: [:0] i1 = undefined;
Expand Down

0 comments on commit c262205

Please sign in to comment.