@@ -64,11 +64,11 @@ pub fn main() !void {
6464
6565 for (class_file .methods .items ) | method | {
6666 const name = method .getName ().bytes ;
67+ if (std .mem .eql (u8 , name , "<init>" )) {
68+ try constructor_overloads .append (method );
69+ continue ;
70+ }
6771 if (method .access_flags .static ) {
68- if (std .mem .eql (u8 , name , "<init>" )) {
69- try constructor_overloads .append (method );
70- continue ;
71- }
7272 const entry = try static_method_overloads .getOrPut (name );
7373 if (! entry .found_existing ) entry .value_ptr .* = std .ArrayList (cf .MethodInfo ).init (arena_alloc );
7474 try entry .value_ptr .* .append (method );
@@ -79,22 +79,26 @@ pub fn main() !void {
7979 try entry .value_ptr .* .append (method );
8080 }
8181
82+ std .log .info ("Found {} constructors" , .{
83+ constructor_overloads .items .len ,
84+ });
85+
8286 // Write methods
8387
8488 var constructors = std .ArrayList (u8 ).init (arena_alloc );
8589 defer constructors .deinit ();
8690
87- try writeConstructors (constructor_overloads .items , arena_alloc , constructors .writer ());
91+ try writeConstructors (constructor_overloads .items , constructors .writer ());
8892
8993 var static_method_accessors = std .ArrayList (u8 ).init (arena_alloc );
9094 defer static_method_accessors .deinit ();
9195
92- // {
93- // var iter = static_method_overloads.iterator();
94- // while (iter.next()) |entry| {
95- // try writeStaticMethodAccessors (entry.key_ptr.*, entry.value_ptr.*.items, arena_alloc, static_method_accessors.writer());
96- // }
97- // }
96+ {
97+ var iter = static_method_overloads .iterator ();
98+ while (iter .next ()) | entry | {
99+ try writeStaticMethod (entry .key_ptr .* , entry .value_ptr .* .items , arena_alloc , static_method_accessors .writer ());
100+ }
101+ }
98102
99103 var method_accessors = std .ArrayList (u8 ).init (arena_alloc );
100104 defer method_accessors .deinit ();
@@ -280,33 +284,71 @@ fn writeMethodDecls(methods: []cf.MethodInfo, writer: anytype) !void {
280284 }
281285}
282286
283- fn writeConstructors (methods : []cf.MethodInfo , allocator : std.mem.Allocator , writer : anytype ) ! void {
287+ fn writeConstructors (methods : []cf.MethodInfo , writer : anytype ) ! void {
288+ if (methods .len == 0 ) return ;
289+ try writer .writeAll ("\n " );
290+
291+ try std .fmt .format (writer ,
292+ \\ pub fn new(self: @This(), env: *jui.JNIEnv, descriptor: []const u8, args: ?[*]const jui.jvalue) !*Instance {{
293+ \\ const method_id = @field(self.Class.methods, "<init>" ++ descriptor) orelse method_id: {{
294+ \\ @field(self.Class.methods, "<init>" ++ descriptor) = try env.getMethodId(self.class, "<init>", descriptor);
295+ \\ break :method_id @field(self.Class.methods, "<init>" ++ descriptor).?;
296+ \\ }};
297+ \\ const object = try env.newObject(self.class, method_id, args);
298+ \\ return Instance {{ .class = self, .object = object }};
299+ \\ }}
300+ \\
301+ , .{});
302+ }
303+
304+ fn writeStaticMethod (name : []const u8 , methods : []cf.MethodInfo , allocator : std.mem.Allocator , writer : anytype ) ! void {
284305 if (methods .len > 0 ) try writer .writeAll ("\n " );
285- for (methods ) | method | {
286- const name = method .getName ().bytes ;
287- if (! std .mem .eql (u8 , name , "<init>" )) continue ;
288306
307+ // TODO: make sure the method_name is a valid identifier string
308+
309+ var overloads = std .ArrayList (u8 ).init (allocator );
310+ defer overloads .deinit ();
311+ try overloads .writer ().print (" const {s}_overloads = &[_][]const u8{{" , .{name });
312+
313+ var return_types = std .ArrayList (u8 ).init (allocator );
314+ defer return_types .deinit ();
315+ try return_types .writer ().print (" const {s}_return_types = &[_]type{{" , .{name });
316+
317+ for (methods ) | method | {
289318 const descriptor = method .getDescriptor ().bytes ;
290319 var descriptor_info = try jui .descriptors .parseString (allocator , descriptor );
320+ defer descriptor_info .deinit (allocator );
291321 std .debug .assert (descriptor_info .* == .method );
292- try std .fmt .format (writer ,
293- \\ pub fn @"<init>{[descriptor]s}"(self: @This(), env: *jui.JNIEnv, args: anytype) !*@This() {{
294- \\ const method_id = self.methods.@"<init>{[descriptor]s}" orelse method_id: {{
295- \\ self.methods.@"<init>{[descriptor]s}" = try env.getMethodId(self.class, "<init>", "{[descriptor]s}");
296- \\ break :method_id self.methods.@"<init>{[descriptor]s}".?;
297- \\ }};
298- \\ comptime var arg_array = [_]jui.jvalue{{}};
299- \\ inline for (args) |arg| {{
300- \\ arg_array ++ .{{jui.jvalue.fromValue(arg)}};
301- \\ }}
302- \\ const object = try env.newObject(self.class, method_id, &arg_array);
303- \\ return Instance {{ .class = self, .object = object }};
304- \\ }}
305- \\
306- , .{
307- .descriptor = descriptor ,
308- });
322+
323+ try overloads .writer ().writeAll ("\n \" " );
324+ try overloads .writer ().writeAll (descriptor );
325+ try overloads .writer ().writeAll ("\" ," );
326+
327+ try return_types .writer ().writeAll ("\n " );
328+ try return_types .writer ().writeAll (descriptorAsTypeString (descriptor_info .* .method .return_type .* ));
329+ try return_types .writer ().writeAll ("," );
309330 }
331+
332+ try overloads .writer ().writeAll ("\n };" );
333+ try return_types .writer ().writeAll ("\n };" );
334+
335+ try std .fmt .format (writer ,
336+ \\{[overloads]s}
337+ \\{[return_types]s}
338+ \\ pub fn {[name]s}(self: @This(), env: *jui.JNIEnv, comptime descriptor: []const u8, args: ?[*]const jui.jvalue) !jui.bindings.returnTypeLookup(descriptor, {[name]s}_overloads, {[name]s}_return_types) {{
339+ \\ const method_id = @field(self.Class.methods, "{[name]s}" ++ descriptor) orelse method_id: {{
340+ \\ @field(self.Class.methods, "{[name]s}" ++ descriptor) = try env.getMethodId(self.class, "{[name]s}", descriptor);
341+ \\ break :method_id @field(self.Class.methods, "{[name]s}" ++ descriptor).?;
342+ \\ }};
343+ \\ const object = try env.newObject(self.class, method_id, arg_array);
344+ \\ return Instance {{ .class = self, .object = object }};
345+ \\ }}
346+ \\
347+ , .{
348+ .name = name ,
349+ .overloads = overloads .items ,
350+ .return_types = return_types .items ,
351+ });
310352}
311353
312354fn descriptorAsTypeString (descriptor : jui.descriptors.Descriptor ) []const u8 {
0 commit comments