fix: Support zig 0.14.0-dev
Some checks are pending
Test / build (push) Waiting to run

This commit is contained in:
Kalle Carlbark 2025-01-18 15:05:30 +01:00
parent 9b8ba849b0
commit 47b842d6b8
6 changed files with 35 additions and 35 deletions

View file

@ -26,7 +26,7 @@ pub fn build(b: *std.Build) !void {
}); });
tests.linkSystemLibrary("objc"); tests.linkSystemLibrary("objc");
tests.linkFramework("Foundation"); tests.linkFramework("Foundation");
try addAppleSDK(b, &tests.root_module); try addAppleSDK(b, tests.root_module);
b.installArtifact(tests); b.installArtifact(tests);
const test_step = b.step("test", "Run tests"); const test_step = b.step("test", "Run tests");

View file

@ -1,13 +1,13 @@
const std = @import("std"); const std = @import("std");
const assert = std.debug.assert; const assert = std.debug.assert;
const alloc = std.heap.raw_c_allocator;
const objc = @import("main.zig"); const objc = @import("main.zig");
// We have to use the raw C allocator for all heap allocation in here // We have to use the raw C allocator for all heap allocation in here
// because the objc runtime expects `malloc` to be used. If you don't use // because the objc runtime expects `malloc` to be used. If you don't use
// malloc you'll get segfaults because the objc runtime will try to free // malloc you'll get segfaults because the objc runtime will try to free
// the memory with `free`. // the memory with `free`.
const alloc = std.heap.raw_c_allocator;
/// Creates a new block type with captured (closed over) values. /// Creates a new block type with captured (closed over) values.
/// ///
/// The CapturesArg is the a struct of captured values that will become /// The CapturesArg is the a struct of captured values that will become
@ -34,7 +34,7 @@ pub fn Block(
) type { ) type {
return struct { return struct {
const Self = @This(); const Self = @This();
const captures_info = @typeInfo(Captures).Struct; const captures_info = @typeInfo(Captures).@"struct";
const InvokeFn = FnType(anyopaque); const InvokeFn = FnType(anyopaque);
const descriptor: Descriptor = .{ const descriptor: Descriptor = .{
.reserved = 0, .reserved = 0,
@ -63,7 +63,7 @@ pub fn Block(
var ctx = try alloc.create(Context); var ctx = try alloc.create(Context);
errdefer alloc.destroy(ctx); errdefer alloc.destroy(ctx);
const flags: BlockFlags = .{ .stret = @typeInfo(Return) == .Struct }; const flags: BlockFlags = .{ .stret = @typeInfo(Return) == .@"struct" };
ctx.isa = NSConcreteStackBlock; ctx.isa = NSConcreteStackBlock;
ctx.flags = @bitCast(flags); ctx.flags = @bitCast(flags);
ctx.invoke = @ptrCast(func); ctx.invoke = @ptrCast(func);
@ -120,7 +120,7 @@ pub fn Block(
} }
return @Type(.{ return @Type(.{
.Fn = .{ .@"fn" = .{
.calling_convention = .C, .calling_convention = .C,
.is_generic = false, .is_generic = false,
.is_var_args = false, .is_var_args = false,
@ -135,40 +135,40 @@ pub fn Block(
/// This is the type of a block structure that is passed as the first /// This is the type of a block structure that is passed as the first
/// argument to any block invocation. See Block. /// argument to any block invocation. See Block.
fn BlockContext(comptime Captures: type, comptime InvokeFn: type) type { fn BlockContext(comptime Captures: type, comptime InvokeFn: type) type {
const captures_info = @typeInfo(Captures).Struct; const captures_info = @typeInfo(Captures).@"struct";
var fields: [captures_info.fields.len + 5]std.builtin.Type.StructField = undefined; var fields: [captures_info.fields.len + 5]std.builtin.Type.StructField = undefined;
fields[0] = .{ fields[0] = .{
.name = "isa", .name = "isa",
.type = ?*anyopaque, .type = ?*anyopaque,
.default_value = null, .default_value_ptr = null,
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(*anyopaque), .alignment = @alignOf(*anyopaque),
}; };
fields[1] = .{ fields[1] = .{
.name = "flags", .name = "flags",
.type = c_int, .type = c_int,
.default_value = null, .default_value_ptr = null,
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(c_int), .alignment = @alignOf(c_int),
}; };
fields[2] = .{ fields[2] = .{
.name = "reserved", .name = "reserved",
.type = c_int, .type = c_int,
.default_value = null, .default_value_ptr = null,
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(c_int), .alignment = @alignOf(c_int),
}; };
fields[3] = .{ fields[3] = .{
.name = "invoke", .name = "invoke",
.type = *const InvokeFn, .type = *const InvokeFn,
.default_value = null, .default_value_ptr = null,
.is_comptime = false, .is_comptime = false,
.alignment = @typeInfo(*const InvokeFn).Pointer.alignment, .alignment = @typeInfo(*const InvokeFn).pointer.alignment,
}; };
fields[4] = .{ fields[4] = .{
.name = "descriptor", .name = "descriptor",
.type = *const Descriptor, .type = *const Descriptor,
.default_value = null, .default_value_ptr = null,
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(*Descriptor), .alignment = @alignOf(*Descriptor),
}; };
@ -183,14 +183,14 @@ fn BlockContext(comptime Captures: type, comptime InvokeFn: type) type {
fields[i] = .{ fields[i] = .{
.name = capture.name, .name = capture.name,
.type = capture.type, .type = capture.type,
.default_value = null, .default_value_ptr = null,
.is_comptime = false, .is_comptime = false,
.alignment = capture.alignment, .alignment = capture.alignment,
}; };
} }
return @Type(.{ return @Type(.{
.Struct = .{ .@"struct" = .{
.layout = .@"extern", .layout = .@"extern",
.fields = &fields, .fields = &fields,
.decls = &.{}, .decls = &.{},

View file

@ -6,7 +6,7 @@ pub const c = @cImport({
/// This is a funky helper to help with the fact that some macOS /// This is a funky helper to help with the fact that some macOS
/// SDKs have an i8 return value for bools and some have stdbool. /// SDKs have an i8 return value for bools and some have stdbool.
pub fn boolResult(comptime Fn: type, result: anytype) bool { pub fn boolResult(comptime Fn: type, result: anytype) bool {
const fn_info = @typeInfo(Fn).Fn; const fn_info = @typeInfo(Fn).@"fn";
return switch (fn_info.return_type.?) { return switch (fn_info.return_type.?) {
bool => result, bool => result,
i8 => result == 1, i8 => result == 1,

View file

@ -57,8 +57,8 @@ pub const Class = struct {
// imp should be a function with C calling convention // imp should be a function with C calling convention
// whose first two arguments are a `c.id` and a `c.SEL`. // whose first two arguments are a `c.id` and a `c.SEL`.
pub fn replaceMethod(self: Class, name: [:0]const u8, imp: anytype) void { pub fn replaceMethod(self: Class, name: [:0]const u8, imp: anytype) void {
const fn_info = @typeInfo(@TypeOf(imp)).Fn; const fn_info = @typeInfo(@TypeOf(imp)).@"fn";
assert(fn_info.calling_convention == .C); assert(fn_info.calling_convention.eql(.c));
assert(fn_info.is_var_args == false); assert(fn_info.is_var_args == false);
assert(fn_info.params.len >= 2); assert(fn_info.params.len >= 2);
assert(fn_info.params[0].type == c.id); assert(fn_info.params[0].type == c.id);
@ -71,8 +71,8 @@ pub const Class = struct {
// whose first two arguments are a `c.id` and a `c.SEL`. // whose first two arguments are a `c.id` and a `c.SEL`.
pub fn addMethod(self: Class, name: [:0]const u8, imp: anytype) !bool { pub fn addMethod(self: Class, name: [:0]const u8, imp: anytype) !bool {
const Fn = @TypeOf(imp); const Fn = @TypeOf(imp);
const fn_info = @typeInfo(Fn).Fn; const fn_info = @typeInfo(Fn).@"fn";
assert(fn_info.calling_convention == .C); assert(fn_info.calling_convention.eql(.c));
assert(fn_info.is_var_args == false); assert(fn_info.is_var_args == false);
assert(fn_info.params.len >= 2); assert(fn_info.params.len >= 2);
assert(fn_info.params[0].type == c.id); assert(fn_info.params[0].type == c.id);

View file

@ -83,14 +83,14 @@ pub const Encoding = union(enum) {
c.Class, objc.Class => .class, c.Class, objc.Class => .class,
c.id, objc.Object => .object, c.id, objc.Object => .object,
else => switch (@typeInfo(T)) { else => switch (@typeInfo(T)) {
.Array => |arr| .{ .array = .{ .len = arr.len, .arr_type = arr.child } }, .array => |arr| .{ .array = .{ .len = arr.len, .arr_type = arr.child } },
.Struct => .{ .structure = .{ .struct_type = T, .show_type_spec = true } }, .@"struct" => .{ .structure = .{ .struct_type = T, .show_type_spec = true } },
.Union => .{ .@"union" = .{ .@"union" => .{ .@"union" = .{
.union_type = T, .union_type = T,
.show_type_spec = true, .show_type_spec = true,
} }, } },
.Pointer => |ptr| .{ .pointer = .{ .ptr_type = T, .size = ptr.size } }, .pointer => |ptr| .{ .pointer = .{ .ptr_type = T, .size = ptr.size } },
.Fn => |fn_info| .{ .function = fn_info }, .@"fn" => |fn_info| .{ .function = fn_info },
else => @compileError("unsupported type: " ++ @typeName(T)), else => @compileError("unsupported type: " ++ @typeName(T)),
}, },
}; };
@ -129,7 +129,7 @@ pub const Encoding = union(enum) {
}, },
.structure => |s| { .structure => |s| {
const struct_info = @typeInfo(s.struct_type); const struct_info = @typeInfo(s.struct_type);
assert(struct_info.Struct.layout == .@"extern"); assert(struct_info.@"struct".layout == .@"extern");
// Strips the fully qualified type name to leave just the // Strips the fully qualified type name to leave just the
// type name. Used in naming the Struct in an encoding. // type name. Used in naming the Struct in an encoding.
@ -141,7 +141,7 @@ pub const Encoding = union(enum) {
// of the struct (determined by levels of pointer indirection) // of the struct (determined by levels of pointer indirection)
if (s.show_type_spec) { if (s.show_type_spec) {
try writer.writeAll("="); try writer.writeAll("=");
inline for (struct_info.Struct.fields) |field| { inline for (struct_info.@"struct".fields) |field| {
const field_encode = init(field.type); const field_encode = init(field.type);
try field_encode.format(fmt, options, writer); try field_encode.format(fmt, options, writer);
} }
@ -151,7 +151,7 @@ pub const Encoding = union(enum) {
}, },
.@"union" => |u| { .@"union" => |u| {
const union_info = @typeInfo(u.union_type); const union_info = @typeInfo(u.union_type);
assert(union_info.Union.layout == .@"extern"); assert(union_info.@"union".layout == .@"extern");
// Strips the fully qualified type name to leave just the // Strips the fully qualified type name to leave just the
// type name. Used in naming the Union in an encoding // type name. Used in naming the Union in an encoding
@ -163,7 +163,7 @@ pub const Encoding = union(enum) {
// of the Union (determined by levels of pointer indirection) // of the Union (determined by levels of pointer indirection)
if (u.show_type_spec) { if (u.show_type_spec) {
try writer.writeAll("="); try writer.writeAll("=");
inline for (union_info.Union.fields) |field| { inline for (union_info.@"union".fields) |field| {
const field_encode = init(field.type); const field_encode = init(field.type);
try field_encode.format(fmt, options, writer); try field_encode.format(fmt, options, writer);
} }
@ -174,7 +174,7 @@ pub const Encoding = union(enum) {
.bitfield => |b| try writer.print("b{}", .{b}), // not sure if needed from Zig -> Obj-C .bitfield => |b| try writer.print("b{}", .{b}), // not sure if needed from Zig -> Obj-C
.pointer => |p| { .pointer => |p| {
switch (p.size) { switch (p.size) {
.One => { .one => {
// get the pointer info (count of levels of direction // get the pointer info (count of levels of direction
// and the underlying type) // and the underlying type)
const pointer_info = indirectionCountAndType(p.ptr_type); const pointer_info = indirectionCountAndType(p.ptr_type);
@ -206,7 +206,7 @@ pub const Encoding = union(enum) {
} }
}, },
.function => |fn_info| { .function => |fn_info| {
assert(fn_info.calling_convention == .C); assert(fn_info.calling_convention.eql(.c));
// Return type is first in a method encoding // Return type is first in a method encoding
const ret_type_enc = init(fn_info.return_type.?); const ret_type_enc = init(fn_info.return_type.?);
@ -230,8 +230,8 @@ fn indirectionCountAndType(comptime T: type) struct {
} { } {
var WalkType = T; var WalkType = T;
var count: usize = 0; var count: usize = 0;
while (@typeInfo(WalkType) == .Pointer) : (count += 1) { while (@typeInfo(WalkType) == .pointer) : (count += 1) {
WalkType = @typeInfo(WalkType).Pointer.child; WalkType = @typeInfo(WalkType).pointer.child;
} }
return .{ .child = WalkType, .indirection_levels = count }; return .{ .child = WalkType, .indirection_levels = count };

View file

@ -174,7 +174,7 @@ fn MsgSendFn(
comptime Target: type, comptime Target: type,
comptime Args: type, comptime Args: type,
) type { ) type {
const argsInfo = @typeInfo(Args).Struct; const argsInfo = @typeInfo(Args).@"struct";
assert(argsInfo.is_tuple); assert(argsInfo.is_tuple);
// Target must always be an "id". Lots of types (Class, Object, etc.) // Target must always be an "id". Lots of types (Class, Object, etc.)
@ -203,7 +203,7 @@ fn MsgSendFn(
}; };
return @Type(.{ return @Type(.{
.Fn = .{ .@"fn" = .{
.calling_convention = .C, .calling_convention = .C,
.is_generic = false, .is_generic = false,
.is_var_args = false, .is_var_args = false,