fix: handle optional primitive types in @TypeOf annotations
- Treat []const u8 as string primitive, not array (fixes ?[]const u8) - Optional primitives generate ?T = null (e.g., ?[]const u8 = null) - Added test for optional string type annotation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
.{
|
.{
|
||||||
.name = .pugz,
|
.name = .pugz,
|
||||||
.version = "0.3.14",
|
.version = "0.3.15",
|
||||||
.fingerprint = 0x822db0790e17621d, // Changing this has security and trust implications.
|
.fingerprint = 0x822db0790e17621d, // Changing this has security and trust implications.
|
||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
.dependencies = .{},
|
.dependencies = .{},
|
||||||
|
|||||||
@@ -814,17 +814,23 @@ pub const Codegen = struct {
|
|||||||
try self.write(" } = .{}");
|
try self.write(" } = .{}");
|
||||||
} else if (type_info.primitive_type) |prim| {
|
} else if (type_info.primitive_type) |prim| {
|
||||||
// Primitive type with appropriate default
|
// Primitive type with appropriate default
|
||||||
try self.write(prim);
|
if (type_info.is_optional) {
|
||||||
if (std.mem.eql(u8, prim, "[]const u8")) {
|
try self.write("?");
|
||||||
try self.write(" = \"\"");
|
try self.write(prim);
|
||||||
} else if (std.mem.eql(u8, prim, "bool")) {
|
try self.write(" = null");
|
||||||
try self.write(" = false");
|
|
||||||
} else if (std.mem.startsWith(u8, prim, "i") or std.mem.startsWith(u8, prim, "u")) {
|
|
||||||
try self.write(" = 0");
|
|
||||||
} else if (std.mem.startsWith(u8, prim, "f")) {
|
|
||||||
try self.write(" = 0.0");
|
|
||||||
} else {
|
} else {
|
||||||
// Unknown type, no default
|
try self.write(prim);
|
||||||
|
if (std.mem.eql(u8, prim, "[]const u8")) {
|
||||||
|
try self.write(" = \"\"");
|
||||||
|
} else if (std.mem.eql(u8, prim, "bool")) {
|
||||||
|
try self.write(" = false");
|
||||||
|
} else if (std.mem.startsWith(u8, prim, "i") or std.mem.startsWith(u8, prim, "u")) {
|
||||||
|
try self.write(" = 0");
|
||||||
|
} else if (std.mem.startsWith(u8, prim, "f")) {
|
||||||
|
try self.write(" = 0.0");
|
||||||
|
} else {
|
||||||
|
// Unknown type, no default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback: string
|
// Fallback: string
|
||||||
@@ -1103,6 +1109,12 @@ pub fn parseTypeHintSpec(allocator: Allocator, spec: []const u8) !TypeInfo {
|
|||||||
remaining = remaining[1..];
|
remaining = remaining[1..];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Treat []const u8 as a string primitive, not an array
|
||||||
|
if (std.mem.eql(u8, remaining, "[]const u8")) {
|
||||||
|
info.primitive_type = remaining;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for array prefix []
|
// Check for array prefix []
|
||||||
if (std.mem.startsWith(u8, remaining, "[]")) {
|
if (std.mem.startsWith(u8, remaining, "[]")) {
|
||||||
info.is_array = true;
|
info.is_array = true;
|
||||||
@@ -1336,3 +1348,35 @@ test "zig_codegen - @TypeOf with non-optional @import type" {
|
|||||||
try std.testing.expect(std.mem.indexOf(u8, zig_code, "data.config.title") != null);
|
try std.testing.expect(std.mem.indexOf(u8, zig_code, "data.config.title") != null);
|
||||||
try std.testing.expect(std.mem.indexOf(u8, zig_code, "config_title") == null);
|
try std.testing.expect(std.mem.indexOf(u8, zig_code, "config_title") == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "zig_codegen - @TypeOf with optional string type" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
const source =
|
||||||
|
\\//- @TypeOf(_logo_url): ?[]const u8
|
||||||
|
\\if _logo_url
|
||||||
|
\\ img(src=_logo_url)
|
||||||
|
;
|
||||||
|
|
||||||
|
var parse_result = try template.parseWithSource(allocator, source);
|
||||||
|
defer parse_result.deinit(allocator);
|
||||||
|
|
||||||
|
const fields = try extractFieldNames(allocator, parse_result.ast);
|
||||||
|
defer {
|
||||||
|
for (fields) |field| allocator.free(field);
|
||||||
|
allocator.free(fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
try std.testing.expectEqual(@as(usize, 1), fields.len);
|
||||||
|
try std.testing.expectEqualStrings("_logo_url", fields[0]);
|
||||||
|
|
||||||
|
var cg = Codegen.init(allocator);
|
||||||
|
defer cg.deinit();
|
||||||
|
|
||||||
|
const zig_code = try cg.generate(parse_result.ast, "render", fields, null);
|
||||||
|
defer allocator.free(zig_code);
|
||||||
|
|
||||||
|
// Should be ?[]const u8 = null, not []const const u8 = &.{}
|
||||||
|
try std.testing.expect(std.mem.indexOf(u8, zig_code, "?[]const u8 = null") != null);
|
||||||
|
try std.testing.expect(std.mem.indexOf(u8, zig_code, "[]const const") == null);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user