diff --git a/src/engines/v8/generate.zig b/src/engines/v8/generate.zig index 886e574..9e1501b 100644 --- a/src/engines/v8/generate.zig +++ b/src/engines/v8/generate.zig @@ -291,7 +291,7 @@ fn getArgs( comptime var arg_real: refl.Type = undefined; comptime { - if (try refl.Type.variadic(arg.underT())) |arg_v| { + if (try refl.Type.variadic(arg.underT(), all_T)) |arg_v| { arg_real = arg_v; } else { arg_real = arg; @@ -389,7 +389,7 @@ fn freeArgs(alloc: std.mem.Allocator, comptime func: refl.Func, obj: anytype) !v } // free varidadic slices - if (try refl.Type.variadic(arg_T.underT()) != null) { + if (try refl.Type.variadic(arg_T.underT(), null) != null) { const val = @field(obj, arg_T.name.?).?; // NOTE: variadic are optional by design alloc.free(@field(val, "slice")); diff --git a/src/reflect.zig b/src/reflect.zig index e3f05d5..8f513d7 100644 --- a/src/reflect.zig +++ b/src/reflect.zig @@ -222,15 +222,19 @@ pub const Type = struct { // find if T is a VariadicType // and returns it as a reflect.Type - pub fn variadic(comptime T: type) !?Type { + pub fn variadic(comptime T: type, comptime structs: ?[]Struct) !?Type { std.debug.assert(@inComptime()); - const tt = Type._variadic(T) orelse return null; + const TT = Type._variadic(T) orelse return null; // avoid infinite calls - if (Type._is_variadic(tt)) return error.TypeVariadicNested; + if (Type._is_variadic(TT)) return error.TypeVariadicNested; - return try Type.reflect(tt, null); + var tt = try Type.reflect(TT, null); + if (structs) |all| { + try tt.lookup(all); + } + return tt; } // check that user-defined types have been provided as an API @@ -257,7 +261,7 @@ pub const Type = struct { } // if variadic, lookup the concrete type - var variadic_type = try Type.variadic(self.underT()); + var variadic_type = try Type.variadic(self.underT(), null); if (variadic_type) |*tt| { return tt.lookup(structs); } @@ -765,6 +769,7 @@ pub const Struct = struct { } fn lookupTypes(comptime self: *Struct, comptime structs: []Struct) Error!void { + try self.value.lookup(structs); if (self.has_constructor) { try self.constructor.lookupTypes(structs); } diff --git a/src/tests/types_complex_test.zig b/src/tests/types_complex_test.zig index f057ffc..c684065 100644 --- a/src/tests/types_complex_test.zig +++ b/src/tests/types_complex_test.zig @@ -54,6 +54,17 @@ const MyVariadic = struct { return true; } + const VariadicList = Variadic(MyList); + + pub fn _myListLen(_: MyVariadic, variadic: ?VariadicList) u8 { + return @as(u8, @intCast(variadic.?.slice.len)); + } + + pub fn _myListFirst(_: MyVariadic, variadic: ?VariadicList) ?u8 { + if (variadic.?.slice.len == 0) return null; + return variadic.?.slice[0]._first(); + } + pub fn deinit(_: *MyVariadic, _: std.mem.Allocator) void {} }; @@ -189,6 +200,8 @@ pub fn exec( .{ .src = "myVariadic.first('a_str', true, false, true, false)", .ex = "true" }, .{ .src = "myVariadic.last(true, false)", .ex = "false" }, .{ .src = "myVariadic.empty()", .ex = "true" }, + .{ .src = "myVariadic.myListLen(myList)", .ex = "1" }, + .{ .src = "myVariadic.myListFirst(myList)", .ex = "1" }, }; try tests.checkCases(js_env, &variadic);