diff --git a/src/Class/AttributeInfo.zig b/src/Class/AttributeInfo.zig index 1b4c6af..50fd96d 100644 --- a/src/Class/AttributeInfo.zig +++ b/src/Class/AttributeInfo.zig @@ -417,7 +417,7 @@ pub const AttributeInfo = union(enum) { try parameter.indentedFormat(w, depth, parameter_indent, constant_pool); } }, - //.module, + .module => |attr| try attr.indentedFormat(w, depth, indent, constant_pool), .module_packages => |attr| { try w.splatByteAll(' ', depth * indent); _ = try w.write("packages:\n"); @@ -840,6 +840,19 @@ pub const InnerClasses = struct { inner_name_index: u16, inner_class_access_flags: InnerClassAccessFlags, + pub const InnerClassAccessFlags = EnumFlags(enum(u16) { + public = 0x0001, + private = 0x0002, + protected = 0x0004, + static = 0x0008, + final = 0x0010, + interface = 0x0200, + abstract = 0x0400, + synthetic = 0x1000, + annotation = 0x2000, + @"enum" = 0x4000, + }); + pub fn indentedFormat( self: *const InnerClass, w: *std.Io.Writer, @@ -899,19 +912,6 @@ pub const InnerClasses = struct { } }; - pub const InnerClassAccessFlags = EnumFlags(enum(u16) { - public = 0x0001, - private = 0x0002, - protected = 0x0004, - static = 0x0008, - final = 0x0010, - interface = 0x0200, - abstract = 0x0400, - synthetic = 0x1000, - annotation = 0x2000, - @"enum" = 0x4000, - }); - pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self { const number_of_classes = try input.takeInt(u16, .big); const classes = try allocator.alloc(InnerClass, number_of_classes); @@ -1560,6 +1560,46 @@ pub const Module = struct { synthetic = 0x1000, mandated = 0x8000, }); + + pub fn indentedFormat( + self: *const Requires, + w: *std.Io.Writer, + depth: usize, + indent: u8, + constant_pool: []const ?ConstantPoolInfo, + ) std.Io.Writer.Error!void { + const requires_ = self.requires(constant_pool) catch return error.WriteFailed; + try w.splatByteAll(' ', depth * indent); + _ = try w.write("requires:\n"); + try requires_.indentedFormat(w, depth, indent + 1, constant_pool); + + try w.splatByteAll(' ', depth * indent); + try w.print("flags: {f}\n", .{ self.requires_flags }); + + const version = self.requiresVersion(constant_pool) catch return error.WriteFailed; + if (version) |v| { + try w.splatByteAll(' ', depth * indent); + _ = try w.write("version:\n"); + try v.indentedFormat(w, depth, indent + 1, constant_pool); + } + } + + pub fn requires(self: *const Requires, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo { + const requires_index = self.requires_index - 1; + if (requires_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[requires_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .module) return ResolveError.InvalidConstantType; + return cp_info.?; + } + + pub fn requiresVersion(self: *const Requires, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo { + if (self.requires_version_index == 0) return null; + const requires_version_index = self.requires_version_index - 1; + if (requires_version_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[requires_version_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType; + return cp_info.?; + } }; pub const Exports = struct { @@ -1571,6 +1611,48 @@ pub const Module = struct { synthetic = 0x1000, mandated = 0x8000, }); + + pub fn indentedFormat( + self: *const Exports, + w: *std.Io.Writer, + depth: usize, + indent: u8, + constant_pool: []const ?ConstantPoolInfo, + ) std.Io.Writer.Error!void { + const exports_ = self.exports(constant_pool) catch return error.WriteFailed; + try w.splatByteAll(' ', depth * indent); + _ = try w.write("exports:\n"); + try exports_.indentedFormat(w, depth, indent + 1, constant_pool); + + try w.splatByteAll(' ', depth * indent); + try w.print("flags: {f}\n", .{ self.exports_flags }); + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("exports_to:\n"); + var exports_to_indent = indent; + for (self.exports_to_indeces, 0..) |exports_to_index, i| { + exports_to_indent += 1; + defer exports_to_indent -= 1; + + const index = exports_to_index - 1; + + if (index >= constant_pool.len) return error.WriteFailed; + const cp_info = constant_pool[index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .module) return error.WriteFailed; + + try w.splatByteAll(' ', depth * exports_to_indent); + try w.print("{d}:\n", .{ i }); + try cp_info.?.indentedFormat(w, depth, exports_to_indent + 1, constant_pool); + } + } + + pub fn exports(self: *const Exports, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo { + const exports_index = self.exports_index - 1; + if (exports_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[exports_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .package) return ResolveError.InvalidConstantType; + return cp_info.?; + } }; pub const Opens = struct { @@ -1582,11 +1664,92 @@ pub const Module = struct { synthetic = 0x1000, mandated = 0x8000, }); + + pub fn indentedFormat( + self: *const Opens, + w: *std.Io.Writer, + depth: usize, + indent: u8, + constant_pool: []const ?ConstantPoolInfo, + ) std.Io.Writer.Error!void { + const opens_ = self.opens(constant_pool) catch return error.WriteFailed; + try w.splatByteAll(' ', depth * indent); + _ = try w.write("opens:\n"); + try opens_.indentedFormat(w, depth, indent + 1, constant_pool); + + try w.splatByteAll(' ', depth * indent); + try w.print("flags: {f}\n", .{ self.opens_flags }); + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("opens_to:\n"); + var opens_to_indent = indent; + for (self.opens_to_indeces, 0..) |opens_to_index, i| { + opens_to_indent += 1; + defer opens_to_indent -= 1; + + const index = opens_to_index - 1; + + if (index >= constant_pool.len) return error.WriteFailed; + const cp_info = constant_pool[index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .module) return error.WriteFailed; + + try w.splatByteAll(' ', depth * opens_to_indent); + try w.print("{d}:\n", .{ i }); + try cp_info.?.indentedFormat(w, depth, opens_to_indent + 1, constant_pool); + } + } + + pub fn opens(self: *const Opens, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo { + const opens_index = self.opens_index - 1; + if (opens_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[opens_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .package) return ResolveError.InvalidConstantType; + return cp_info.?; + } }; pub const Provides = struct { provides_index: u16, provides_with_indeces: []u16, + + pub fn indentedFormat( + self: *const Provides, + w: *std.Io.Writer, + depth: usize, + indent: u8, + constant_pool: []const ?ConstantPoolInfo, + ) std.Io.Writer.Error!void { + const provides_ = self.provides(constant_pool) catch return error.WriteFailed; + try w.splatByteAll(' ', depth * indent); + _ = try w.write("provides:\n"); + try provides_.indentedFormat(w, depth, indent + 1, constant_pool); + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("provides_with:\n"); + var provides_with_indent = indent; + for (self.provides_with_indeces, 0..) |provides_with_index, i| { + provides_with_indent += 1; + defer provides_with_indent -= 1; + + const index = provides_with_index - 1; + + if (index >= constant_pool.len) return error.WriteFailed; + const cp_info = constant_pool[index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed; + + try w.splatByteAll(' ', depth * provides_with_indent); + try w.print("{d}:\n", .{ i }); + try cp_info.?.indentedFormat(w, depth, provides_with_indent + 1, constant_pool); + } + } + + pub fn provides(self: *const Provides, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo { + const provides_index = self.provides_index - 1; + if (provides_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[provides_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType; + return cp_info.?; + } }; pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self { @@ -1698,6 +1861,112 @@ pub const Module = struct { } allocator.free(self.provides); } + + pub fn indentedFormat( + self: *const Module, + w: *std.Io.Writer, + depth: usize, + indent: u8, + constant_pool: []const ?ConstantPoolInfo, + ) std.Io.Writer.Error!void { + const module_name = self.moduleName(constant_pool) catch return error.WriteFailed; + try w.splatByteAll(' ', depth * indent); + _ = try w.write("name:\n"); + try module_name.indentedFormat(w, depth, indent + 1, constant_pool); + + try w.splatByteAll(' ', depth * indent); + try w.print("flags: {f}\n", .{ self.module_flags }); + + const module_version = self.moduleVersion(constant_pool) catch return error.WriteFailed; + if (module_version) |m| { + try w.splatByteAll(' ', depth * indent); + _ = try w.write("version:\n"); + try m.indentedFormat(w, depth, indent + 1, constant_pool); + } + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("requires:\n"); + var requires_indent = indent; + for (self.requires, 0..) |requires, i| { + requires_indent += 1; + defer requires_indent -= 1; + + try w.splatByteAll(' ', depth * requires_indent); + try w.print("{d}:\n", .{ i }); + try requires.indentedFormat(w, depth, requires_indent, constant_pool); + } + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("exports:\n"); + var exports_indent = indent; + for (self.exports, 0..) |exports, i| { + exports_indent += 1; + defer exports_indent -= 1; + + try w.splatByteAll(' ', depth * exports_indent); + try w.print("{d}:\n", .{ i }); + try exports.indentedFormat(w, depth, exports_indent, constant_pool); + } + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("opens:\n"); + var opens_indent = indent; + for (self.opens, 0..) |opens, i| { + opens_indent += 1; + defer opens_indent -= 1; + + try w.splatByteAll(' ', depth * opens_indent); + try w.print("{d}:\n", .{ i }); + try opens.indentedFormat(w, depth, opens_indent, constant_pool); + } + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("uses:\n"); + var uses_indent = indent; + for (self.uses_indeces, 0..) |uses_index, i| { + uses_indent += 1; + defer uses_indent -= 1; + + const index = uses_index - 1; + + if (index >= constant_pool.len) return error.WriteFailed; + const cp_info = constant_pool[index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed; + + try w.splatByteAll(' ', depth * uses_indent); + try w.print("{d}:\n", .{ i }); + try cp_info.?.indentedFormat(w, depth, uses_indent + 1, constant_pool); + } + + try w.splatByteAll(' ', depth * indent); + _ = try w.write("provides:\n"); + var provides_indent = indent; + for (self.provides, 0..) |provides, i| { + provides_indent += 1; + defer provides_indent -= 1; + + try w.splatByteAll(' ', depth * provides_indent); + try w.print("{d}:\n", .{ i }); + try provides.indentedFormat(w, depth, provides_indent, constant_pool); + } + } + + pub fn moduleName(self: *const Module, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo { + const module_name_index = self.module_name_index - 1; + if (module_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[module_name_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType; + return cp_info.?; + } + + pub fn moduleVersion(self: *const Module, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo { + if (self.module_version_index == 0) return null; + const module_version_index = self.module_version_index - 1; + if (module_version_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex; + const cp_info = constant_pool[module_version_index]; + if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType; + return cp_info.?; + } }; pub const ModulePackages = struct {